From ffc52312097ac25aaca6d20a132242f5f0670c5b Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 5 Feb 2011 17:33:53 +0800 Subject: [PATCH] Implemented `dispense acct =` - also starting on moving item database to cokebank --- items.cfg | 4 +-- src/client/main.c | 61 ++++++++++++++++++++++++++++++++++++--- src/cokebank.h | 5 ++++ src/server/handler_coke.c | 38 +++++++++++++++++++++++- src/server/server.c | 2 ++ 5 files changed, 103 insertions(+), 7 deletions(-) diff --git a/items.cfg b/items.cfg index 49b7ed9..c2b27e1 100644 --- a/items.cfg +++ b/items.cfg @@ -18,5 +18,5 @@ pseudo 3 3500 polo postorder # Polo Shirt! (With UCC Sun Logo) pseudo 4 2500 membership # here comes the money! # Snack machine -snack 13 128 Smiths Salt & Vinegar -snack 33 128 Smiths Original +#snack 13 128 Smiths Salt & Vinegar +#snack 33 128 Smiths Original diff --git a/src/client/main.c b/src/client/main.c index 0aea926..72dffdf 100644 --- a/src/client/main.c +++ b/src/client/main.c @@ -49,6 +49,7 @@ void PrintAlign(int Row, int Col, int Width, const char *Left, char Pad1, const void PopulateItemList(int Socket); int DispenseItem(int Socket, int ItemID); int Dispense_AlterBalance(int Socket, const char *Username, int Ammount, const char *Reason); + int Dispense_SetBalance(int Socket, const char *Username, int Balance, const char *Reason); int Dispense_Give(int Socket, const char *Username, int Ammount, const char *Reason); int Dispense_Donate(int Socket, int Ammount, const char *Reason); int Dispense_EnumUsers(int Socket); @@ -128,6 +129,9 @@ int main(int argc, char *argv[]) continue; } + // + // `dispense acct` + // - if( strcmp(arg, "acct") == 0 ) { // Connect to server @@ -158,8 +162,19 @@ int main(int argc, char *argv[]) // argv[i+2]: Ammount // argv[i+3]: Reason - // Alter balance - Dispense_AlterBalance(sock, argv[i+1], atoi(argv[i+2]), argv[i+3]); + if( argv[i+2][0] == '=' ) { + // Set balance + if( argv[i+2][1] != '0' && atoi(&argv[i+2][1]) == 0 ) { + fprintf(stderr, "Error: Invalid balance to be set\n"); + exit(1); + } + + Dispense_SetBalance(sock, argv[i+1], atoi(argv[i+2]+1), argv[i+3]); + } + else { + // Alter balance + Dispense_AlterBalance(sock, argv[i+1], atoi(argv[i+2]), argv[i+3]); + } } // Show user information @@ -197,7 +212,7 @@ int main(int argc, char *argv[]) } // // `dispense user` - // - User administration (Wheel Only) + // - User administration (Admin Only) if( strcmp(arg, "user") == 0 ) { // Check argument count @@ -299,6 +314,7 @@ int main(int argc, char *argv[]) } else { + // Very basic dispense interface for( i = 0; i < giNumItems; i ++ ) { printf("%2i %s:%i\t%3i %s\n", i, gaItems[i].Type, gaItems[i].ID, gaItems[i].Price, gaItems[i].Desc); @@ -342,6 +358,7 @@ void ShowUsage(void) { printf( "Usage:\n" + " == Everyone ==\n" " dispense\n" " Show interactive list\n" " dispense \n" @@ -350,10 +367,14 @@ void ShowUsage(void) " Give money to another user\n" " dispense donate \"\"\n" " Donate to the club\n" + " == Coke members == \n" " dispense acct []\n" " Show user balances\n" " dispense acct [+-] \"\"\n" - " Alter a account value (Coke members only)\n" + " Alter a account value\n" + " == Dispense administrators ==\n" + " dispense acct = \"\"\n" + " Set an account balance\n" " dispense user add \n" " Create new coke account (Admins only)\n" " dispense user type \n" @@ -997,6 +1018,38 @@ int Dispense_AlterBalance(int Socket, const char *Username, int Ammount, const c return -1; } +/** + * \brief Set a user's balance + * \note Only avaliable to dispense admins + */ +int Dispense_SetBalance(int Socket, const char *Username, int Balance, const char *Reason) +{ + char *buf; + int responseCode; + + sendf(Socket, "SET %s %i %s\n", Username, Balance, Reason); + buf = ReadLine(Socket); + + responseCode = atoi(buf); + free(buf); + + switch(responseCode) + { + case 200: return 0; // OK + case 403: // Not in coke + fprintf(stderr, "You are not an admin\n"); + return 1; + case 404: // Unknown user + fprintf(stderr, "Unknown user '%s'\n", Username); + return 2; + default: + fprintf(stderr, "Unknown response code %i\n", responseCode); + return -1; + } + + return -1; +} + /** * \brief Give money to another user */ diff --git a/src/cokebank.h b/src/cokebank.h index 7c7997e..ed4dff1 100644 --- a/src/cokebank.h +++ b/src/cokebank.h @@ -28,6 +28,11 @@ */ typedef struct sAcctIterator tAcctIterator; +/** + * \brief Iterator for a collection of items + */ +typedef struct sItemIterator tItemIterator; + /** * \brief Flag values for the \a Flags parameter to Bank_Iterator */ diff --git a/src/server/handler_coke.c b/src/server/handler_coke.c index 4043cfc..62ea17f 100644 --- a/src/server/handler_coke.c +++ b/src/server/handler_coke.c @@ -19,6 +19,7 @@ #include #define READ_TIMEOUT 2 // 2 seconds for ReadChar +#define TRACE_COKE 1 // === IMPORTS === @@ -67,6 +68,10 @@ int Coke_CanDispense(int UNUSED(User), int Item) if( giCoke_SerialFD == -1 ) return -2; + #if TRACE_COKE + printf("Coke_CanDispense: Flushing"); + #endif + // Flush the input buffer { char tmpbuf[512]; @@ -76,6 +81,9 @@ int Coke_CanDispense(int UNUSED(User), int Item) // Wait for a prompt ret = 0; do { + #if TRACE_COKE + printf("Coke_DoDispense: sending 'd7'"); + #endif write(giCoke_SerialFD, "d7\r\n", 4); } while( WaitForColon() && ret++ < 3 ); @@ -86,10 +94,17 @@ int Coke_CanDispense(int UNUSED(User), int Item) // TODO: Handle "not ok" response to D7 + #if TRACE_COKE + printf("Coke_CanDispense: sending 's%i'", Item); + #endif + // Ask the coke machine sprintf(tmp, "s%i\r\n", Item); write(giCoke_SerialFD, tmp, 4); + #if TRACE_COKE + printf("Coke_CanDispense: reading response"); + #endif // Read from the machine (ignoring empty lines) while( (ret = ReadLine(sizeof(tmp)-1, tmp)) == 0 ); printf("ret = %i, tmp = '%s'\n", ret, tmp); @@ -106,6 +121,10 @@ int Coke_CanDispense(int UNUSED(User), int Item) } return -1; } + + #if TRACE_COKE + printf("Coke_CanDispense: wait for the prompt again"); + #endif // Eat rest of response WaitForColon(); @@ -121,6 +140,10 @@ int Coke_CanDispense(int UNUSED(User), int Item) status = &tmp[ matches[3].rm_so ]; printf("Machine responded slot status '%s'\n", status); + + #if TRACE_COKE + printf("Coke_CanDispense: done"); + #endif if( strcmp(status, "full") == 0 ) return 0; @@ -143,18 +166,27 @@ int Coke_DoDispense(int UNUSED(User), int Item) if( giCoke_SerialFD == -1 ) return -2; + #if TRACE_COKE + printf("Coke_DoDispense: flushing input"); + #endif // Flush the input buffer { char tmpbuf[512]; read(giCoke_SerialFD, tmpbuf, sizeof(tmpbuf)); } - + // Wait for prompt i = 0; do { + #if TRACE_COKE + printf("Coke_DoDispense: sending 'd7'"); + #endif write(Item, "d7\r\n", 4); } while( WaitForColon() && i++ < 3 ); + #if TRACE_COKE + printf("Coke_DoDispense: sending 'd%i'", Item); + #endif // Dispense sprintf(tmp, "d%i\r\n", Item); write(giCoke_SerialFD, tmp, 4); @@ -172,6 +204,10 @@ int Coke_DoDispense(int UNUSED(User), int Item) if( ret == -1 ) return -1; WaitForColon(); // Eat up rest of response + + #if TRACE_COKE + printf("Coke_DoDispense: done"); + #endif // TODO: Regex if( strcmp(tmp, "ok") == 0 ) { diff --git a/src/server/server.c b/src/server/server.c index ca4aceb..8138f1e 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -61,6 +61,7 @@ void Server_Cmd_DISPENSE(tClient *Client, char *Args); void Server_Cmd_GIVE(tClient *Client, char *Args); void Server_Cmd_DONATE(tClient *Client, char *Args); void Server_Cmd_ADD(tClient *Client, char *Args); +void Server_Cmd_SET(tClient *Client, char *Args); void Server_Cmd_ENUMUSERS(tClient *Client, char *Args); void Server_Cmd_USERINFO(tClient *Client, char *Args); void _SendUserInfo(tClient *Client, int UserID); @@ -86,6 +87,7 @@ const struct sClientCommand { {"GIVE", Server_Cmd_GIVE}, {"DONATE", Server_Cmd_DONATE}, {"ADD", Server_Cmd_ADD}, + {"SET", Server_Cmd_SET}, {"ENUM_USERS", Server_Cmd_ENUMUSERS}, {"USER_INFO", Server_Cmd_USERINFO}, {"USER_ADD", Server_Cmd_USERADD}, -- 2.20.1