async Task <string> SellStock(MySqlConnection cnn, UserCommandType command) { using (MySqlCommand cmd = new MySqlCommand()) { cmd.Connection = cnn; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "sell_stock"; cmd.Parameters.AddWithValue("@pUserId", command.username); cmd.Parameters["@pUserId"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pStock", command.stockSymbol); cmd.Parameters["@pStock"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pStockAmount", (int)(command.funds)); cmd.Parameters["@pStockAmount"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pServerTime", Unix.TimeStamp.ToString()); cmd.Parameters["@pServerTime"].Direction = ParameterDirection.Input; cmd.Parameters.Add(new MySqlParameter("@success", MySqlDbType.Bit)); cmd.Parameters["@success"].Direction = ParameterDirection.Output; cmd.Parameters.Add(new MySqlParameter("@message", MySqlDbType.Text)); cmd.Parameters["@message"].Direction = ParameterDirection.Output; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); if (!Convert.ToBoolean(cmd.Parameters["@success"].Value)) { return(Convert.ToString(cmd.Parameters["@message"].Value)); } return(null); } }
async Task <string> SellCommit(MySqlConnection cnn, UserCommandType command) { using (MySqlCommand cmd = new MySqlCommand()) { cmd.Connection = cnn; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "sell_commit"; cmd.Parameters.AddWithValue("@pUserId", command.username); cmd.Parameters["@pUserId"].Direction = ParameterDirection.Input; cmd.Parameters.Add(new MySqlParameter("@pServerTime", MySqlDbType.Text)); cmd.Parameters["@pServerTime"].Direction = ParameterDirection.Input; cmd.Parameters.Add(new MySqlParameter("@pStock", MySqlDbType.Text)); cmd.Parameters["@pStock"].Direction = ParameterDirection.Output; cmd.Parameters.Add(new MySqlParameter("@pStockAmount", MySqlDbType.Int32)); cmd.Parameters["@pStockAmount"].Direction = ParameterDirection.Output; cmd.Parameters.Add(new MySqlParameter("@success", MySqlDbType.Bit)); cmd.Parameters["@success"].Direction = ParameterDirection.Output; cmd.Parameters.Add(new MySqlParameter("@message", MySqlDbType.Text)); cmd.Parameters["@message"].Direction = ParameterDirection.Output; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); if (!Convert.ToBoolean(cmd.Parameters["@success"].Value)) { return(Convert.ToString(cmd.Parameters["@message"].Value)); } command.funds = Convert.ToDecimal(cmd.Parameters["@pStockAmount"].Value); command.stockSymbol = Convert.ToString(cmd.Parameters["@pStock"].Value); return($"Successfully sold ${String.Format("{0:0.00}", command.funds / 100m)} worth of {command.stockSymbol}"); } }
async Task <string> BuyCancel(MySqlConnection cnn, UserCommandType command) { using (MySqlCommand cmd = new MySqlCommand()) { cmd.Connection = cnn; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "buy_cancel_stock"; cmd.Parameters.AddWithValue("@pUserId", command.username); cmd.Parameters["@pUserId"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pServerTime", Unix.TimeStamp); cmd.Parameters["@pServerTime"].Direction = ParameterDirection.Input; cmd.Parameters.Add(new MySqlParameter("@success", MySqlDbType.Bit)); cmd.Parameters["@success"].Direction = ParameterDirection.Output; cmd.Parameters.Add(new MySqlParameter("@message", MySqlDbType.Text)); cmd.Parameters["@message"].Direction = ParameterDirection.Output; cmd.Parameters.Add(new MySqlParameter("@pStock", MySqlDbType.VarChar, 3)); cmd.Parameters["@pStock"].Direction = ParameterDirection.Output; cmd.Parameters.Add(new MySqlParameter("@pStockAmount", MySqlDbType.Int32)); cmd.Parameters["@pStockAmount"].Direction = ParameterDirection.Output; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); if (!Convert.ToBoolean(cmd.Parameters["@success"].Value)) { return(LogErrorEvent(command, Convert.ToString(cmd.Parameters["@message"].Value))); } return($"Successfully cancelled {Convert.ToDecimal(cmd.Parameters["@pStockAmount"].Value) / 100m} worth of {cmd.Parameters["@pStock"].Value}."); } }
async Task <string> CheckUserStock(MySqlCommand cmd, UserCommandType command) { cmd.CommandText = "get_user_stock"; cmd.Parameters.AddWithValue("@pUserId", command.username); cmd.Parameters["@pUserId"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pStock", command.stockSymbol); cmd.Parameters["@pStock"].Direction = ParameterDirection.Input; cmd.Parameters.Add("@pStockAmount", DbType.Int32); cmd.Parameters["@pStockAmount"].Direction = ParameterDirection.Output; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); if (cmd.Parameters["@pStockAmount"].Value == DBNull.Value) { return(LogErrorEvent(command, "User does not exist or does not have this stock")); } if (Convert.ToInt32(cmd.Parameters["@pStockAmount"].Value) < command.funds) { return(LogErrorEvent(command, "Insufficient user stocks")); } command.fundsSpecified = false; return(await SellTriggerTimer.StartOrUpdateTimer(command).ConfigureAwait(false));; }
public static async Task <string> StartOrUpdateTimer(UserCommandType command) { BuyTriggerTimer timer; bool newTimer; lock (_timerLock) { newTimer = !_timers.TryGetValue(command.stockSymbol, out timer); if (newTimer) { if (command.fundsSpecified) { return("Set buy amount before creating trigger"); } timer = new BuyTriggerTimer(command.stockSymbol); if (!_timers.TryAdd(command.stockSymbol, timer)) { LogDebugEvent(command, "Error adding timer"); } } } var msg = await timer.AddOrUpdateUser(command).ConfigureAwait(false); if (newTimer) { var _ = timer.Start(); } return(msg); }
protected override async Task <string> DataReceived(UserCommandType command) { string result = ""; try { var trigger = SellTriggerTimer.RemoveUserTrigger(command.username, command.stockSymbol); if (trigger != null) { command.fundsSpecified = true; command.funds = trigger.Amount; // Check if trigger exists MySQL db = new MySQL(); result = await db.PerformTransaction(CancelSell, command).ConfigureAwait(false); } else { return(LogErrorEvent(command, $"No trigger set for {command.stockSymbol}")); } } catch (Exception ex) { LogDebugEvent(command, ex.Message); return(LogErrorEvent(command, "Error processing command")); } return(result); }
// ExecuteClient() Method protected override async Task <string> DataReceived(UserCommandType command) { if (!command.fundsSpecified || command.funds <= 0) { return("Invalid funds specified."); } string result; try { MySQL db = new MySQL(); await db.PerformTransaction(AddMoney, command).ConfigureAwait(false); result = $"Successfully added ${String.Format("{0:0.00}", command.funds / 100m)} into {command.username}'s account"; LogTransactionEvent(command, "add"); } catch (Exception e) { LogDebugEvent(command, e.Message); result = LogErrorEvent(command, "Error occurred adding money."); } return(result); }
async Task <string> GetStock(UserCommandType command) { var delay = 500; try { string result = null; do { ConnectedServices cs = clientConnections.GetOrAdd(command.username, new ConnectedServices()); ServiceConnection conn = await cs.GetServiceConnectionAsync(Service.QUOTE_SERVICE).ConfigureAwait(false); if (conn == null) { throw new Exception("Failed to connect to service"); } result = await conn.SendAsync(command, true).ConfigureAwait(false); if (result == null) { await Task.Delay(delay).ConfigureAwait(false); // Short delay before tring again } } while (result == null); return(result); } catch (Exception ex) { LogDebugEvent(command, ex.Message); return(null); } }
async Task <string> GetQuote(UserCommandType command) { ServiceConnection conn = new ServiceConnection(Server.QUOTE_SERVER); var quote = await conn.Send($"{command.stockSymbol},{command.username}", true).ConfigureAwait(false); var cost = LogQuoteServerEvent(command, quote); var result = $"{cost},{Unix.TimeStamp}"; //redisConn.StringSet(command.stockSymbol.ToUpper(), result); return(result); }
public override int ReadFrom(byte[] Buffer, int StartIndex = 0) { int cursor = StartIndex; commandType = (UserCommandType)Buffer[cursor]; cursor++; // Type (1 byte) Array.Copy(Buffer, cursor, Data, 0, Data.Length); cursor += Data.Length; return cursor - StartIndex; }
public override int ReadFrom(byte[] Buffer, int StartIndex = 0) { int cursor = StartIndex; commandType = (UserCommandType)Buffer[cursor]; cursor++; // Type (1 byte) Array.Copy(Buffer, cursor, Data, 0, Data.Length); cursor += Data.Length; return(cursor - StartIndex); }
async Task <string> SetUserMoney(MySqlCommand cmd, UserCommandType command) { cmd.CommandText = "hold_user_money"; cmd.Parameters.AddWithValue("@pUserId", command.username); cmd.Parameters["@pUserId"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pMoney", (int)command.funds); cmd.Parameters["@pMoney"].Direction = ParameterDirection.Input; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); return(null); }
void LogDebugEvent(UserCommandType command, string err) { DebugType bug = new DebugType() { timestamp = Unix.TimeStamp.ToString(), server = Server.WEB_SERVER.Abbr, transactionNum = command.transactionNum, command = command.command, debugMessage = err }; _writer.WriteRecord(bug); }
public async Task HandleMessage(TGMessageDTO dto, User user, Message message) { var chatType = dto.Chat.GetChatType(); if (chatType != ChatType.Private) { if (dto.Text.ToUpper().Contains(ApplicationDefaults.CNBotUserName)) { // Only use command in private chat await _telegramHttpClient.SendMessage(TGSendMessageDTO.BuildOnlyUseInPrivateMessage(dto.Chat.Id, dto.MessageId)); } //If not my command. Nothing to do return; } var utcNow = DateTime.UtcNow; UserCommandType commandType = dto.GetCommandType(); if (commandType == UserCommandType.None) { var lastCommand = await _userService.FindLastCommand(user.Id); if (lastCommand == null || lastCommand.Completed) { // No command found. So we just show the default message await _telegramHttpClient.SendMessage(TGSendMessageDTO.BuildUnrecognizedMessage(dto.Chat.Id, dto.MessageId)); return; } else { commandType = lastCommand.Type; } } var command = new UserCommand { Created = utcNow, Completed = false, Type = commandType, UserId = user.Id, Text = dto.Text }; await _userService.AddCommand(command); await this.HandleCommand(dto, command, message); if (command.Type != UserCommandType.Remove && dto.Entities != null && dto.Entities.Any()) { _eventBus.Publish(new TelegramMessageEntityExtractEvent(dto.Entities)); } }
public bool Validate(string[] args, ref UserCommandType command, out string error) { if (args.Length != _argLength) { error = _usage; return(false); } if (_usernameIndex > 0) { command.username = args[_usernameIndex].Trim(); if (string.IsNullOrEmpty(command.username)) { error = "Invalid username"; return(false); } } if (_filenameIndex > 0) { command.filename = args[_filenameIndex].Trim(); if (string.IsNullOrEmpty(command.filename)) { error = "Invalid username"; return(false); } } if (_fundsIndex > 0) { if (!Decimal.TryParse(args[_fundsIndex], out decimal funds) || funds < 0) { error = "Invalid amount specified"; return(false); } command.fundsSpecified = true; command.funds = funds * 100; } if (_stockIndex > 0) { command.stockSymbol = args[_stockIndex]; if (command.stockSymbol.Length > 3 || command.stockSymbol.Length < 1 || !System.Text.RegularExpressions.Regex.IsMatch(command.stockSymbol, @"^[a-zA-Z]+$")) { error = "Stock symbol is invalid"; return(false); } } error = null; return(true); }
static async Task <string> HoldUserStock(MySqlCommand cmd, UserCommandType command) { cmd.CommandText = "hold_user_stock"; cmd.Parameters.AddWithValue("@pUserId", command.username); cmd.Parameters["@pUserId"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pStock", command.stockSymbol); cmd.Parameters["@pStock"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pStockAmount", (int)command.funds); cmd.Parameters["@pStockAmount"].Direction = ParameterDirection.Input; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); return(null); }
private async Task AddMoney(MySqlConnection cnn, UserCommandType command) { using (MySqlCommand cmd = new MySqlCommand()) { cmd.Connection = cnn; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "add_user"; cmd.Parameters.AddWithValue("@pUserId", command.username); cmd.Parameters["@pUserId"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pFunds", command.funds); cmd.Parameters["@pFunds"].Direction = ParameterDirection.Input; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); } }
protected override async Task <string> DataReceived(UserCommandType command) { string result; try { MySQL db = new MySQL(); result = await db.PerformTransaction(BuyCancel, command).ConfigureAwait(false); } catch (Exception e) { result = LogErrorEvent(command, "Error getting account details"); LogDebugEvent(command, e.Message); } return(result); }
protected void LogTransactionEvent(UserCommandType command, string action) { AccountTransactionType transaction = new AccountTransactionType() { timestamp = Unix.TimeStamp.ToString(), server = ServiceDetails.Abbr, transactionNum = command.transactionNum, action = action, username = command.username }; if (command.fundsSpecified) { transaction.funds = command.funds / 100m; } Auditor.WriteRecord(transaction); }
protected override async Task <string> DataReceived(UserCommandType command) { string result = ""; try { // Check user account for cash, notify if insufficient funds MySQL db = new MySQL(); result = await db.PerformTransaction(SetAmount, command).ConfigureAwait(false); } catch (Exception ex) { LogDebugEvent(command, ex.Message); return(LogErrorEvent(command, "Error processing command")); } return(result); }
async Task <string> SetAmount(MySqlConnection cnn, UserCommandType command) { using (MySqlCommand cmd = new MySqlCommand()) { cmd.Connection = cnn; cmd.CommandType = CommandType.StoredProcedure; var msg = await CheckUserStock(cmd, command).ConfigureAwait(false); if (msg != null) { return(LogErrorEvent(command, msg)); } cmd.Parameters.Clear(); await HoldUserStock(cmd, command).ConfigureAwait(false); } LogTransactionEvent(command, "remove"); return($"Sell amount set successfully for stock {command.stockSymbol}"); }
protected void LogDebugEvent(UserCommandType command, string err) { DebugType bug = new DebugType() { timestamp = Unix.TimeStamp.ToString(), server = ServiceDetails.Abbr, transactionNum = command.transactionNum, command = command.command, debugMessage = err, fundsSpecified = command.fundsSpecified }; if (command.fundsSpecified) { bug.funds = command.funds / 100m; } Auditor.WriteRecord(bug); }
async Task <string> CancelBuy(MySqlConnection cnn, UserCommandType command) { using (MySqlCommand cmd = new MySqlCommand()) { cmd.Connection = cnn; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "return_user_money"; cmd.Parameters.AddWithValue("@pUserId", command.username); cmd.Parameters["@pUserId"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pMoney", command.funds); cmd.Parameters["@pMoney"].Direction = ParameterDirection.Input; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); LogTransactionEvent(command, "add"); return($"Successfully removed trigger to buy stock {command.stockSymbol}"); } }
protected override async Task <string> DataReceived(UserCommandType command) { try { command.fundsSpecified = true; var msg = await SellTriggerTimer.StartOrUpdateTimer(command).ConfigureAwait(false); if (msg == null) { return($"Trigger amount set successfully for stock {command.stockSymbol}"); } return(LogErrorEvent(command, msg)); } catch (Exception ex) { LogDebugEvent(command, ex.Message); return(LogErrorEvent(command, "Error processing command.")); } }
int LogQuoteServerEvent(UserCommandType command, string quote) { //Cost,StockSymbol,UserId,Timestamp,CryptoKey string[] args = quote.Split(","); QuoteServerType stockQuote = new QuoteServerType() { username = args[2], server = Server.QUOTE_SERVER.Abbr, price = Convert.ToDecimal(args[0]), transactionNum = command.transactionNum, stockSymbol = args[1], timestamp = Unix.TimeStamp.ToString(), quoteServerTime = args[3], cryptokey = args[4] }; Auditor.WriteRecord(stockQuote); return((int)(stockQuote.price * 100)); }
async Task <string> CancelSell(MySqlConnection cnn, UserCommandType command) { using (MySqlCommand cmd = new MySqlCommand()) { cmd.Connection = cnn; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "return_user_stock"; cmd.Parameters.AddWithValue("@pUserId", command.username); cmd.Parameters["@pUserId"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pStock", command.stockSymbol); cmd.Parameters["@pStock"].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("@pStockAmount", command.funds); cmd.Parameters["@pStockAmount"].Direction = ParameterDirection.Input; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); return($"Successfully removed trigger to sell stock {command.stockSymbol}"); } }
/* * Logs interserver communication * @param command The user command that is driving the process */ protected void LogServerEvent(UserCommandType command) { SystemEventType sysEvent = new SystemEventType() { timestamp = Unix.TimeStamp.ToString(), server = ServiceDetails.Abbr, transactionNum = command.transactionNum, username = command.username, fundsSpecified = command.fundsSpecified, command = command.command, filename = command.filename, stockSymbol = command.stockSymbol }; if (command.fundsSpecified) { sysEvent.funds = command.funds / 100m; } Auditor.WriteRecord(sysEvent); }
protected override async Task <string> DataReceived(UserCommandType command) { try { //IDatabase redisConn = Muxer.GetDatabase(1); var result = await _quoteCache.GetOrCreate(command.stockSymbol, () => GetQuote(command), v => (Unix.TimeStamp - Convert.ToInt64(v.Split(",")[1])) < 60000); if (command.command != commandType.SET_BUY_TRIGGER && command.command != commandType.SET_SELL_TRIGGER) { return(result.Split(",")[0]); } return(result); } catch (Exception ex) { Console.WriteLine(ex); return($"Error getting quote"); } }
async Task <string> DisplaySummary(MySqlConnection cnn, UserCommandType command) { using (MySqlCommand cmd = new MySqlCommand()) { cmd.Connection = cnn; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "display_summary"; cmd.Parameters.AddWithValue("@pUserId", command.username); cmd.Parameters["@pUserId"].Direction = ParameterDirection.Input; cmd.Parameters.Add(new MySqlParameter("@pMoney", MySqlDbType.Int32)); cmd.Parameters["@pMoney"].Direction = ParameterDirection.Output; var reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false); StringBuilder stocks = new StringBuilder(); try { while (await reader.ReadAsync()) { // Reads in stock and amount stocks.Append($"{reader.GetString(0)}    ${String.Format("{0:0.00}", Convert.ToDecimal(reader.GetValue(1)) / 100m)}<br>"); } } finally { await reader.CloseAsync(); } var money = Convert.ToDecimal(cmd.Parameters["@pMoney"].Value); if (money == -1) { return("User does not exist"); } return($"User {command.username} has ${String.Format("{0:0.00}", money / 100m)}<br>Stock    Amount<br>" + stocks.ToString()); } }
async Task <string> GetStock(string username, string stockSymbol) { var delay = 500; UserCommandType cmd = new UserCommandType { server = Service.SELL_TRIGGER_SET_SERVICE.Abbr, command = commandType.SET_BUY_TRIGGER, stockSymbol = stockSymbol, username = username }; try { string result = null; do { ConnectedServices cs = clientConnections.GetOrAdd(_stockSymbol, new ConnectedServices()); ServiceConnection conn = await cs.GetServiceConnectionAsync(Service.QUOTE_SERVICE).ConfigureAwait(false); if (conn == null) { throw new Exception("Failed to connect to service"); } result = await conn.SendAsync(cmd, true).ConfigureAwait(false); if (result == null) { await Task.Delay(delay).ConfigureAwait(false); // Short delay before tring again } } while (result == null); return(result); } catch (Exception ex) { LogDebugEvent(cmd, ex.Message); return(null); } }
static void LogDebugEvent(UserCommandType command, string err) { DebugType bug = new DebugType() { timestamp = Unix.TimeStamp.ToString(), server = "BTSVC", debugMessage = err }; if (command != null) { bug.transactionNum = command.transactionNum; bug.command = command.command; bug.fundsSpecified = command.fundsSpecified; if (command.fundsSpecified) { bug.funds = command.funds / 100m; } } _auditWriter.WriteRecord(bug); }
public UserCommandEventArgs(UserCommandType userCommand) { this.userCommand = userCommand; }
public UserCommandGeneric(UserCommandType CommandType, byte[] Data) { this.commandType = CommandType; this.Data = Data; }