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
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);
continue;
}
+ //
+ // `dispense acct`
+ // -
if( strcmp(arg, "acct") == 0 )
{
// Connect to server
// 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
}
//
// `dispense user`
- // - User administration (Wheel Only)
+ // - User administration (Admin Only)
if( strcmp(arg, "user") == 0 )
{
// Check argument count
}
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);
{
printf(
"Usage:\n"
+ " == Everyone ==\n"
" dispense\n"
" Show interactive list\n"
" dispense <item>\n"
" 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"
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
*/
*/
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
*/
#include <regex.h>
#define READ_TIMEOUT 2 // 2 seconds for ReadChar
+#define TRACE_COKE 1
// === IMPORTS ===
if( giCoke_SerialFD == -1 )
return -2;
+ #if TRACE_COKE
+ printf("Coke_CanDispense: Flushing");
+ #endif
+
// Flush the input buffer
{
char tmpbuf[512];
// 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 );
// 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);
}
return -1;
}
+
+ #if TRACE_COKE
+ printf("Coke_CanDispense: wait for the prompt again");
+ #endif
// Eat rest of response
WaitForColon();
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;
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);
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 ) {
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);
{"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},