Implemented `dispense acct <name> =`
authorJohn Hodge <[email protected]>
Sat, 5 Feb 2011 09:33:53 +0000 (17:33 +0800)
committerJohn Hodge <[email protected]>
Sat, 5 Feb 2011 09:33:53 +0000 (17:33 +0800)
- also starting on moving item database to cokebank

items.cfg
src/client/main.c
src/cokebank.h
src/server/handler_coke.c
src/server/server.c

index 49b7ed9..c2b27e1 100644 (file)
--- 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
index 0aea926..72dffdf 100644 (file)
@@ -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 <item>\n"
@@ -350,10 +367,14 @@ void ShowUsage(void)
                "        Give money to another user\n"
                "    dispense donate <ammount> \"<reason>\"\n"
                "        Donate to the club\n"
+               "  == Coke members == \n"
                "    dispense acct [<user>]\n"
                "        Show user balances\n"
                "    dispense acct <user> [+-]<ammount> \"<reason>\"\n"
-               "        Alter a account value (Coke members only)\n"
+               "        Alter a account value\n"
+               "  == Dispense administrators ==\n"
+               "    dispense acct <user> =<ammount> \"<reason>\"\n"
+               "        Set an account balance\n"
                "    dispense user add <user>\n"
                "        Create new coke account (Admins only)\n"
                "    dispense user type <user> <flags>\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
  */
index 7c7997e..ed4dff1 100644 (file)
  */
 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
  */
index 4043cfc..62ea17f 100644 (file)
@@ -19,6 +19,7 @@
 #include <regex.h>
 
 #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 ) {
index ca4aceb..8138f1e 100644 (file)
@@ -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},

UCC git Repository :: git.ucc.asn.au