internal static Transaction Create(bool reply, int transactionId, int taskNumber, int errorCode, byte[] transactionData, out Transaction replyTo) { replyTo = null; try { // Figure out what type is associated with the given ID number. // The default for unknown ID values is the base class. Type transType; if (s_idMap.TryGetValue(transactionId, out transType) == false) { s_log.InfoFormat("Unknown Transaction ID {0}", transactionId); transType = typeof(Transaction); } // Create an instance of that Type. Transaction transaction = (Transaction)Activator.CreateInstance(transType); // Configure the base instance with the fields we have. transaction.Configure(reply, transactionId, taskNumber, errorCode); // Have the transaction parse its own details. transaction.ParseObjects(transactionData); // Look up the transaction that this is a reply to. replyTo = Transaction.GetSourceTransaction(taskNumber); // Return the finished transaction. return transaction; } catch (Exception e) { s_log.ErrorFormat("Exception generating Transaction ID {0}: {1}", transactionId, e.Message); return null; } }
public TransactionEventArgs(Transaction incomingTransaction, Transaction replyToTransaction) { m_incomingTransaction = incomingTransaction; m_replyToTransaction = replyToTransaction; }
internal Status SendTransaction(Transaction transaction) { //TODO: Check socket state for being disconnected. // Validate transaction if (transaction == null) { s_log.ErrorFormat("Cannot send null package."); return Status.Failure; } // Enqueue Package. lock (m_sendQueue) { m_sendQueue.Enqueue(transaction); } // Notify other thread. m_sendEvent.Set(); // Start other thread if necessary. if (m_sendThread == null) { m_sendThread = new Thread(SendLoop); m_sendThread.Name = "Transaction Sending"; m_sendThread.Start(); } return Status.Success; }
public static Status TryParse(ref List<byte> potentialTransaction, out Transaction outTransaction, out Transaction replyToTransaction) { outTransaction = null; replyToTransaction = null; s_log.InfoFormat("Parsing Transaction from {0} bytes.", potentialTransaction.Count); DataUtils.DumpBytes("Parsing received bytes:", potentialTransaction); byte[] transArray = potentialTransaction.ToArray(); int arrayIndex = 0; try { // Parse bytes enough to run the appropriate creator, // followed by a generic data object parser for the details. // Then a factory should be able to make the right transaction. int transactionClass = DataUtils.ReadShort(transArray, ref arrayIndex); bool reply = (transactionClass != 0); // If class is "0", this is not a reply. int transactionId = DataUtils.ReadShort(transArray, ref arrayIndex); int taskNumber = DataUtils.ReadLong(transArray, ref arrayIndex); int errorCode = DataUtils.ReadLong(transArray, ref arrayIndex); int dataLength1 = DataUtils.ReadLong(transArray, ref arrayIndex); // Total transaction size int dataLength2 = DataUtils.ReadLong(transArray, ref arrayIndex); // Size of this part s_log.InfoFormat("Parsed header for Transaction ID {0}", transactionId); if (errorCode != 0) s_log.ErrorFormat("Error code: {0}", errorCode); if (dataLength1 != dataLength2) { s_log.ErrorFormat("Multi-part transactions not supported! ({0},{1})", dataLength1, dataLength2); return Status.Failure; } // Read the exact amount of bytes specified by the header. byte[] transactionData = DataUtils.ReadLength(transArray, ref arrayIndex, dataLength1); // Shuttle off the Transaction data to the factory for more specific parsing. outTransaction = TransactionFactory.Create(reply, transactionId, taskNumber, errorCode, transactionData, out replyToTransaction); // Any additional data in the array needs to be left in the original list. potentialTransaction = DataUtils.CopyRemainder(transArray, ref arrayIndex); return Status.Success; } catch (Exception e) { s_log.ErrorFormat("Exception parsing Transaction: {0}", e.Message); return Status.Failure; } }
private void HandleGotUserInfo(Transaction userInfoTransaction) { s_log.InfoFormat("Received GetUserInfo response."); if (userInfoTransaction == null) return; Message msg = (Message)ObjectFactory.FindObject(userInfoTransaction.Objects, typeof(Message)); Nick nick = (Nick)ObjectFactory.FindObject(userInfoTransaction.Objects, typeof(Nick)); if (msg == null || nick == null) return; string formattedMsg = String.Format("*** User Details for {0}: ***\n\n{1}", nick.Value.Value, msg.Value.Value); // Raise the event. OnUserInfoReceived(new UserInfoEventArgs(formattedMsg)); }
/// <summary> /// Handler for a Transaction response listing the complete userlist. /// NOTE: It is not the responsibility of the Server class to decide how /// the response data is displayed to the user. That is, do NOT /// automatically make this a chat message! /// </summary> private void HandleGetUserList(Transaction userList) { s_log.InfoFormat("Received userlist response."); if (userList == null) return; // Create a new userlist from scratch. List<User> addList = new List<User>(); foreach (HotlineObject obj in userList.Objects) { UserListEntry ule = obj as UserListEntry; if (ule == null) continue; User user = new User(ule); addList.Add(user); } // Send the new full user list as a non-delta list of "adds". OnUserListUpdate(new UserListUpdateEventArgs(addList, null, false)); }
private void HandleLoginResponse(Transaction loginResponse) { s_log.InfoFormat("Received login response: {0}", loginResponse.ErrorCode); if (loginResponse.ErrorCode != 0) { OnDisconnected(new DisconnectedEventArgs("Login failed.")); Disconnect(); } else { // If the error code is zero, the login was succesful. // Some servers return a ServerName object, so print it if found. ServerName serverName = (ServerName)ObjectFactory.FindObject(loginResponse.Objects, typeof(ServerName)); if (ChatReceived != null) { if (serverName == null) { OnConnected(new ConnectedEventArgs("*** Login complete. ***")); } else { string text = String.Format("*** Server Name: {0} ***", serverName.Value.Value); OnConnected(new ConnectedEventArgs(text)); } } } }
private void HandleError(Transaction inTransaction) { s_log.InfoFormat("Received error transaction: {0}", inTransaction.ErrorCode); ErrorMessage errMsg = (ErrorMessage)ObjectFactory.FindObject(inTransaction.Objects, typeof(ErrorMessage)); string text = String.Format("*** Error: {0} ***", errMsg.Value.Value); OnChatReceived(new ChatReceivedEventArgs(text)); }
public Status SendTransaction(Transaction tx) { if (m_channel == null) { s_log.ErrorFormat("Not connected to server."); return Status.Failure; } if (tx == null) { s_log.ErrorFormat("Null transaction provided. Not sending."); return Status.Failure; } // Returns Success if the transaction was successfully queued. return m_channel.SendTransaction(tx); }
public static void AddActiveTransaction(int taskNumber, Transaction transaction) { lock (s_activeTransactions) { s_activeTransactions.Add(taskNumber, transaction); } }