void RecvMoveStopHorizontal(IIPSocket conn, BitStream r) { User user; if ((user = TryGetUser(conn)) != null && (user.IsMovingLeft || user.IsMovingRight)) { if (user.IsPeerTrading) return; user.StopMovingHorizontal(); } }
void RecvMoveStopVertical(IIPSocket conn, BitStream r) { User user; if ((user = TryGetUser(conn)) != null && (user.IsMovingUp || user.IsMovingDown)) { if (user.IsPeerTrading) return; user.StopMovingVertical(); } }
void RecvMoveUp(IIPSocket conn, BitStream r) { User user; if ((user = TryGetUser(conn)) != null && !user.IsMovingUp) { if (user.IsPeerTrading) return; user.MoveUp(); } }
void RecvJump(IIPSocket conn, BitStream r) { User user; if (((user = TryGetUser(conn)) != null) && user.CanJump) { if (user.IsPeerTrading) return; user.Jump(); } }
/// <summary> /// Invokes the <see cref="IMessageProcessor"/> for handle processing a message block. /// </summary> /// <param name="socket">The <see cref="IIPSocket"/> that the data came from.</param> /// <param name="processor">The <see cref="IMessageProcessor"/> to invoke.</param> /// <param name="reader">The <see cref="BitStream"/> containing the data to process.</param> protected override void InvokeProcessor(IIPSocket socket, IMessageProcessor processor, BitStream reader) { // Invoke the processor as normal, but keeping track of the bit position before and after invoking var startBits = reader.PositionBits; base.InvokeProcessor(socket, processor, reader); var endBits = reader.PositionBits; // Update the stats _stats.HandleProcessorInvoked(processor.MsgID, endBits - startBits); }
/// <summary> /// When overridden in the derived class, allows for handling received data from an <see cref="IIPSocket"/>. /// </summary> /// <param name="sender">The <see cref="IIPSocket"/> that the data came from.</param> /// <param name="data">The data that was received.</param> protected override void OnReceiveData(IIPSocket sender, BitStream data) { base.OnReceiveData(sender, data); try { // Process the data _messageProcessorManager.Process(sender, data); } catch (Exception ex) { const string errmsg = "Failed to process received data from `{0}`. Exception: {1}"; if (log.IsWarnEnabled) log.WarnFormat(errmsg, sender, ex); Debug.Fail(string.Format(errmsg, sender, ex)); } }
void RecvSelectAccountCharacter(IIPSocket conn, BitStream r) { ThreadAsserts.IsMainThread(); var index = r.ReadByte(); // Ensure the client is in a valid state to select an account character var userAccount = World.GetUserAccount(conn); if (userAccount == null) return; if (userAccount.User != null) { const string errmsg = "Account `{0}` tried to change characters while a character was already selected."; if (log.IsInfoEnabled) log.InfoFormat(errmsg, userAccount); return; } // Get the CharacterID CharacterID characterID; if (!userAccount.TryGetCharacterID(index, out characterID)) { const string errmsg = "Invalid account character index `{0}` given."; if (log.IsInfoEnabled) log.InfoFormat(errmsg, characterID); return; } // Load the user userAccount.SetUser(World, characterID); var user = userAccount.User; if (user != null) { // Send the MOTD if (!string.IsNullOrEmpty(ServerSettings.Default.MOTD)) { using (var pw = ServerPacket.Chat(ServerSettings.Default.MOTD)) { user.Send(pw, ServerMessageType.GUIChat); } } // Send a notification to the world that the user joined var param = new object[] {user.Name}; World.Send(GameMessage.UserJoinedWorld, ServerMessageType.GUIChat, param); } }
void RecvRequestMapEntityIndex(IIPSocket conn, BitStream r) { var index = r.ReadMapEntityIndex(); // Get the user and their map User user; if ((user = TryGetUser(conn)) == null) return; Map map; if (!TryGetMap(user, out map)) return; // Get the DynamicEntity var de = map.GetDynamicEntity(index); if (de == null) { // The DynamicEntity for the index was null, so tell the client to delete whatever is at that index using (var pw = ServerPacket.RemoveDynamicEntity(index)) { conn.Send(pw, ServerMessageType.Map); } } else { // A DynamicEntity does exist at that index, so tell the client to create it using (var pw = ServerPacket.CreateDynamicEntity(de)) { conn.Send(pw, ServerMessageType.Map); } } }
void RecvSendPrivateMessage(IIPSocket conn, BitStream r) { string TargetName = r.ReadString(); string Text = r.ReadString(); // Get the user to send the message to User TargetChar = World.FindUser(TargetName); string PrivateMessage = TargetName + " Says: " + Text; using (var pw = ServerPacket.ReceivePrivateMessage(PrivateMessage)) { TargetChar.Send(pw, ServerMessageType.GUIChat); } }
void RecvUseWorld(IIPSocket conn, BitStream r) { var useEntityIndex = r.ReadMapEntityIndex(); // Get the map and user User user; Map map; if (!TryGetMap(conn, out user, out map)) return; if (user.IsPeerTrading) return; if (!user.IsAlive) { const string errmsg = "User `{0}` tried to use world entity while dead."; if (log.IsInfoEnabled) log.InfoFormat(errmsg, user); return; } // Grab the DynamicEntity to use var useEntity = map.GetDynamicEntity(useEntityIndex); if (useEntity == null) { const string errmsg = "UseEntity received but usedEntityIndex `{0}` is not a valid DynamicEntity."; Debug.Fail(string.Format(errmsg, useEntityIndex)); if (log.IsErrorEnabled) log.ErrorFormat(errmsg, useEntityIndex); return; } // Ensure the used DynamicEntity is even usable var asUsable = useEntity as IUsableEntity; if (asUsable == null) { const string errmsg = "UseEntity received but useByIndex `{0}` refers to DynamicEntity `{1}` which does " + "not implement IUsableEntity."; Debug.Fail(string.Format(errmsg, useEntityIndex, useEntity)); if (log.IsErrorEnabled) log.WarnFormat(errmsg, useEntityIndex, useEntity); return; } // Use it if (asUsable.Use(user)) { // Notify everyone in the map it was used if (asUsable.NotifyClientsOfUsage) { using (var pw = ServerPacket.UseEntity(useEntity.MapEntityIndex, user.MapEntityIndex)) { map.Send(pw, ServerMessageType.Map); } } } }
void RecvSynchronizeGameTime(IIPSocket conn, BitStream r) { // Just reply immediately with the current game time using (var pw = ServerPacket.SetGameTime(DateTime.Now)) { conn.Send(pw, ServerMessageType.GUI); } }
void RecvSetExp(IIPSocket conn, BitStream r) { var exp = r.ReadInt(); UserInfo.Exp = exp; }
void RecvSetCash(IIPSocket conn, BitStream r) { var cash = r.ReadInt(); UserInfo.Cash = cash; }
void RecvSendInventoryItemInfo(IIPSocket conn, BitStream r) { var slot = r.ReadInventorySlot(); GameplayScreen.InventoryInfoRequester.ReceiveInfo(slot, r); }
void RecvSendEquipmentItemInfo(IIPSocket conn, BitStream r) { var slot = r.ReadEnum <EquipmentSlot>(); GameplayScreen.EquipmentInfoRequester.ReceiveInfo(slot, r); }
void RecvQuestInfo(IIPSocket conn, BitStream r) { QuestInfo.Read(r); }
void RecvPeerTradeEvent(IIPSocket conn, BitStream r) { PeerTradeInfoHandler.Read(r); }
void RecvSellInventoryToShop(IIPSocket conn, BitStream r) { var slot = r.ReadInventorySlot(); var amount = r.ReadByte(); User user; if ((user = TryGetUser(conn)) == null) return; user.ShoppingState.TrySellInventory(slot, amount); }
void RecvStartShopping(IIPSocket conn, BitStream r) { var entityIndex = r.ReadMapEntityIndex(); User user; Map map; if (!TryGetMap(conn, out user, out map)) return; if (user.IsPeerTrading) return; var shopkeeper = map.GetDynamicEntity<Character>(entityIndex); if (shopkeeper == null) return; user.ShoppingState.TryStartShopping(shopkeeper); }
void RecvSetLevel(IIPSocket conn, BitStream r) { var level = r.ReadByte(); UserInfo.Level = level; }
void RecvUseInventoryItem(IIPSocket conn, BitStream r) { var slot = r.ReadInventorySlot(); User user; if ((user = TryGetUser(conn)) == null) return; user.UseInventoryItem(slot); }
void RecvSetStatPoints(IIPSocket conn, BitStream r) { var statPoints = r.ReadInt(); UserInfo.StatPoints = statPoints; }
void RecvAcceptOrTurnInQuest(IIPSocket conn, BitStream r) { var providerIndex = r.ReadMapEntityIndex(); var questID = r.ReadQuestID(); // Get the user User user; if ((user = TryGetUser(conn)) == null || user.Map == null) return; if (user.IsPeerTrading) return; // Get the provider var npc = user.Map.GetDynamicEntity<Character>(providerIndex); var provider = npc as IQuestProvider<User>; if (provider == null) return; // Check the distance and state if (user.Map != npc.Map || user.Map == null || !npc.IsAlive || npc.IsDisposed || user.GetDistance(npc) > GameData.MaxNPCChatDistance) return; // Get the quest var quest = _questManager.GetQuest(questID); if (quest == null) return; // Ensure this provider even provides this quest if (!provider.Quests.Contains(quest)) return; // If the user already has the quest, try to turn it in if (user.ActiveQuests.Contains(quest)) { // Quest already started, try to turn in var success = user.TryFinishQuest(quest); using (var pw = ServerPacket.AcceptOrTurnInQuestReply(questID, success, false)) { user.Send(pw, ServerMessageType.GUI); } } else { // Quest not started yet, try to add it var success = user.TryAddQuest(quest); using (var pw = ServerPacket.AcceptOrTurnInQuestReply(questID, success, true)) { user.Send(pw, ServerMessageType.GUI); } } }
void RecvSetUserChar(IIPSocket conn, BitStream r) { var mapCharIndex = r.ReadMapEntityIndex(); World.UserCharIndex = mapCharIndex; }
static IUserAccount TryGetAccount(IIPSocket conn) { // Check for a valid conn if (conn == null) { const string errmsg = "conn is null."; if (log.IsErrorEnabled) log.Error(errmsg); Debug.Fail(errmsg); return null; } return conn.Tag as IUserAccount; }
/// <summary> /// When overridden in the derived class, allows for handling received data from an <see cref="IIPSocket"/>. /// </summary> /// <param name="sender">The <see cref="IIPSocket"/> that the data came from.</param> /// <param name="data">The data that was received. This <see cref="BitStream"/> instance is reused internally, so it /// is vital that you do NOT hold a reference to it when this method returns. This should be no problem since you should /// not be holding onto raw received data anyways, but if you must, you can always make a deep copy.</param> protected virtual void OnReceiveData(IIPSocket sender, BitStream data) { }
void RecvGuildInfo(IIPSocket conn, BitStream r) { GuildInfo.Read(r); }
/// <summary> /// When overridden in the derived class, allows for handling when the status of an <see cref="IIPSocket"/> changes. /// </summary> /// <param name="sender">The <see cref="IIPSocket"/> who's status has changed.</param> /// <param name="status">The new status.</param> /// <param name="reason">The reason for the status change.</param> protected virtual void OnReceiveStatusChanged(IIPSocket sender, NetConnectionStatus status, string reason) { }
void RecvRaiseStat(IIPSocket conn, BitStream r) { StatType statType; // Get the StatType try { statType = r.ReadEnum<StatType>(); } catch (InvalidCastException) { const string errorMsg = "Received invaild StatType on connection `{0}`."; Debug.Fail(string.Format(errorMsg, conn)); if (log.IsWarnEnabled) log.WarnFormat(errorMsg, conn); return; } // Get the User User user; if ((user = TryGetUser(conn)) == null) return; // Raise the user's stat user.RaiseStat(statType); }
/// <summary> /// Invokes the <see cref="IMessageProcessor"/> for handle processing a message block. /// </summary> /// <param name="socket">The <see cref="IIPSocket"/> that the data came from.</param> /// <param name="processor">The <see cref="IMessageProcessor"/> to invoke.</param> /// <param name="reader">The <see cref="BitStream"/> containing the data to process.</param> protected virtual void InvokeProcessor(IIPSocket socket, IMessageProcessor processor, BitStream reader) { processor.Call(socket, reader); }
void RecvSay(IIPSocket conn, BitStream r) { var text = r.ReadString(GameData.MaxClientSayLength); User user; if ((user = TryGetUser(conn)) == null) return; _sayHandler.Process(user, text); }
/// <summary> /// Handles received data and forwards it to the corresponding <see cref="IMessageProcessor"/>. /// </summary> /// <param name="socket"><see cref="IIPSocket"/> the data came from.</param> /// <param name="data">Data to process.</param> public void Process(IIPSocket socket, BitStream data) { ThreadAsserts.IsMainThread(); // Validate the arguments if (socket == null) { const string errmsg = "socket is null."; Debug.Fail(errmsg); if (log.IsErrorEnabled) { log.Error(errmsg); } return; } if (data == null) { const string errmsg = "data is null."; Debug.Fail(errmsg); if (log.IsErrorEnabled) { log.Error(errmsg); } return; } if (data.Length == 0) { const string errmsg = "data array is empty."; Debug.Fail(errmsg); if (log.IsErrorEnabled) { log.Error(errmsg); } return; } Debug.Assert(data.PositionBits == 0); // Loop through the data until it is emptied while (data.PositionBits < data.LengthBits) { // Get the ID of the message var msgID = ReadMessageID(data); if (log.IsDebugEnabled) { log.DebugFormat("Parsing message ID `{0}`. Stream now at bit position `{1}`.", msgID, data.PositionBits); } // If we get a message ID of 0, we have likely hit the end if (msgID.GetRawValue() == 0) { AssertRestOfStreamIsZero(data); return; } // Find the corresponding processor and call it var processor = GetMessageProcessor(msgID); // Ensure the processor exists if (processor == null) { const string errmsg = "Processor for message ID {0} is null."; if (log.IsErrorEnabled) { log.ErrorFormat(errmsg, msgID); } Debug.Fail(string.Format(errmsg, msgID)); return; } // Ensure the processor contains a valid handler if (processor.Call == null) { const string errmsg = "Processor for message ID {0} contains null Call delegate."; if (log.IsErrorEnabled) { log.ErrorFormat(errmsg, msgID); } Debug.Fail(string.Format(errmsg, msgID)); return; } // Call the processor InvokeProcessor(socket, processor, data); } }
void RecvSelectNPCChatDialogResponse(IIPSocket conn, BitStream r) { var responseIndex = r.ReadByte(); User user; if ((user = TryGetUser(conn)) == null) return; user.ChatState.EnterResponse(responseIndex); }
/// <summary> /// Tries to log in an account. /// </summary> /// <param name="socket">The socket used to communicate with the client.</param> /// <param name="name">The name of the account.</param> /// <param name="password">The account password.</param> /// <param name="userAccount">When this method returns <see cref="AccountLoginResult.Successful"/>, /// contains the <see cref="IUserAccount"/> that was logged in to. Otherwise, this value will be null.</param> /// <returns>If <see cref="AccountLoginResult.Successful"/>, the login was successful. Otherwise, contains /// the reason why the login failed.</returns> public AccountLoginResult Login(IIPSocket socket, string name, string password, out IUserAccount userAccount) { // Try to load the account data var accountTable = DbController.GetQuery <SelectAccountQuery>().TryExecute(name); if (accountTable == null) { userAccount = null; return(AccountLoginResult.InvalidName); } // Check the password var encodedPass = EncodePassword(password); if (!StringComparer.OrdinalIgnoreCase.Equals(encodedPass, accountTable.Password)) { userAccount = null; return(AccountLoginResult.InvalidPassword); } // Check if the account is already logged in to if (accountTable.CurrentIp.HasValue) { if (ServerSettings.Default.AccountDropExistingConnectionWhenInUse) { // Kick existing user so the new connection can enter the account UserAccount existingAccount; lock (_accountsSync) { if (!_accounts.TryGetValue(name, out existingAccount)) { existingAccount = null; } } if (existingAccount != null) { existingAccount.Dispose(); } } else { // Let the existing user stay connected and reject the new connection to the account userAccount = null; return(AccountLoginResult.AccountInUse); } } // Try to mark the account as in use if (!DbController.GetQuery <TrySetAccountIPIfNullQuery>().Execute(accountTable.ID, socket.IP)) { userAccount = null; return(AccountLoginResult.AccountInUse); } // Try to add the new account to the collection lock (_accountsSync) { // If for some reason an account instance already exists, close it UserAccount existingAccount; if (_accounts.TryGetValue(name, out existingAccount)) { const string errmsg = "UserAccount for `{0}` already existing in _accounts collection somehow."; if (log.IsErrorEnabled) { log.ErrorFormat(errmsg, name); } Debug.Fail(string.Format(errmsg, name)); userAccount = null; return(AccountLoginResult.AccountInUse); } // Create the account instance userAccount = new UserAccount(accountTable, socket, this); // Add _accounts.Add(name, (UserAccount)userAccount); } // Load the characters in this account userAccount.LoadCharacterIDs(); // Record the login IP DbController.GetQuery <InsertAccountIPQuery>().Execute(userAccount.ID, socket.IP); return(AccountLoginResult.Successful); }
void RecvStartNPCChatDialog(IIPSocket conn, BitStream r) { var npcIndex = r.ReadMapEntityIndex(); var forceSkipQuestDialog = r.ReadBool(); User user; Map map; if (!TryGetMap(conn, out user, out map)) return; if (user.IsPeerTrading) return; var npc = map.GetDynamicEntity<NPC>(npcIndex); if (npc == null) return; // Check the distance and state if (user.Map != npc.Map || user.Map == null || !npc.IsAlive || npc.IsDisposed || user.GetDistance(npc) > GameData.MaxNPCChatDistance) return; // If the NPC provides any quests that this user can do or turn in, show that instead if (!forceSkipQuestDialog && !npc.Quests.IsEmpty()) { IQuest<User>[] availableQuests; IQuest<User>[] turnInQuests; QuestHelper.GetAvailableQuests(user, npc, out availableQuests, out turnInQuests); if (availableQuests.Length > 0 || turnInQuests.Length > 0) { using (var pw = ServerPacket.StartQuestChatDialog(npcIndex, availableQuests.Select(x => x.QuestID), turnInQuests.Select(x => x.QuestID))) { user.Send(pw, ServerMessageType.GUI); } return; } } // Force-skipped the quest dialog, or there was no available quests, so start the chat dialog user.ChatState.StartChat(npc); }
/// <summary> /// CarWhiteTb14702300 constructor to set default value /// </summary> /// <param name="controlType"></param> /// <param name="carAddr"></param> /// <param name="ipAddr"></param> /// <param name="port"></param> /// <param name="TimeOut"></param> /// <param name="returnsStatus"></param> /// <param name="deviceResponse"></param> /// <param name="socket"></param> public CarWhiteTb14702300(ControllerType controlType, string carAddr, string ipAddr, int port, int TimeOut, bool returnsStatus, IDeviceResponse deviceResponse, IIPSocket socket) : base(controlType, carAddr, ipAddr, port, TimeOut, returnsStatus, deviceResponse, socket) { SetCharacterAttributes(); TargetShelf = 0; }
void RecvSwapInventorySlots(IIPSocket conn, BitStream r) { var a = r.ReadInventorySlot(); var b = r.ReadInventorySlot(); var user = TryGetUser(conn); if (user == null) return; user.Inventory.SwapSlots(a, b); }
void RecvUseWorld(IIPSocket conn, BitStream r) { var useEntityIndex = r.ReadMapEntityIndex(); // Get the map and user User user; Map map; if (!TryGetMap(conn, out user, out map)) { return; } if (user.IsPeerTrading) { return; } if (!user.IsAlive) { const string errmsg = "User `{0}` tried to use world entity while dead."; if (log.IsInfoEnabled) { log.InfoFormat(errmsg, user); } return; } // Grab the DynamicEntity to use var useEntity = map.GetDynamicEntity(useEntityIndex); if (useEntity == null) { const string errmsg = "UseEntity received but usedEntityIndex `{0}` is not a valid DynamicEntity."; Debug.Fail(string.Format(errmsg, useEntityIndex)); if (log.IsErrorEnabled) { log.ErrorFormat(errmsg, useEntityIndex); } return; } // Ensure the used DynamicEntity is even usable var asUsable = useEntity as IUsableEntity; if (asUsable == null) { const string errmsg = "UseEntity received but useByIndex `{0}` refers to DynamicEntity `{1}` which does " + "not implement IUsableEntity."; Debug.Fail(string.Format(errmsg, useEntityIndex, useEntity)); if (log.IsErrorEnabled) { log.WarnFormat(errmsg, useEntityIndex, useEntity); } return; } // Use it if (asUsable.Use(user)) { // Notify everyone in the map it was used if (asUsable.NotifyClientsOfUsage) { using (var pw = ServerPacket.UseEntity(useEntity.MapEntityIndex, user.MapEntityIndex)) { map.Send(pw, ServerMessageType.Map); } } } }
void RecvUnequipItem(IIPSocket conn, BitStream r) { var slot = r.ReadEnum<EquipmentSlot>(); User user; if ((user = TryGetUser(conn)) != null) user.Equipped.RemoveAt(slot); }
void RecvAcceptOrTurnInQuest(IIPSocket conn, BitStream r) { var providerIndex = r.ReadMapEntityIndex(); var questID = r.ReadQuestID(); // Get the user User user; if ((user = TryGetUser(conn)) == null || user.Map == null) { return; } if (user.IsPeerTrading) { return; } // Get the provider var npc = user.Map.GetDynamicEntity <Character>(providerIndex); var provider = npc as IQuestProvider <User>; if (provider == null) { return; } // Check the distance and state if (user.Map != npc.Map || user.Map == null || !npc.IsAlive || npc.IsDisposed || user.GetDistance(npc) > GameData.MaxNPCChatDistance) { return; } // Get the quest var quest = _questManager.GetQuest(questID); if (quest == null) { return; } // Ensure this provider even provides this quest if (!provider.Quests.Contains(quest)) { return; } // If the user already has the quest, try to turn it in if (user.ActiveQuests.Contains(quest)) { // Quest already started, try to turn in var success = user.TryFinishQuest(quest); using (var pw = ServerPacket.AcceptOrTurnInQuestReply(questID, success, false)) { user.Send(pw, ServerMessageType.GUI); } } else { // Quest not started yet, try to add it var success = user.TryAddQuest(quest); using (var pw = ServerPacket.AcceptOrTurnInQuestReply(questID, success, true)) { user.Send(pw, ServerMessageType.GUI); } } }
void RecvUseSkill(IIPSocket conn, BitStream r) { SkillType skillType; MapEntityIndex? targetIndex = null; // Get the SkillType to use try { skillType = r.ReadEnum<SkillType>(); } catch (InvalidCastException) { const string errmsg = "Failed to read SkillType from stream."; if (log.IsWarnEnabled) log.Warn(errmsg); Debug.Fail(errmsg); r.ReadBool(); return; } // Check for a target var hasTarget = r.ReadBool(); if (hasTarget) targetIndex = r.ReadMapEntityIndex(); // Get the user User user; if ((user = TryGetUser(conn)) != null) { // Check that they know the skill if (!user.KnownSkills.Knows(skillType)) user.Send(GameMessage.SkillNotKnown, ServerMessageType.GUIChat); else { // Use the skill user.UseSkill(skillType, GetTargetCharacter(user, targetIndex)); } } }
void RecvSkillStopCasting_ToUser(IIPSocket conn, BitStream r) { GameplayScreen.SkillCastProgressBar.StopCasting(); }
void RecvGetFriends(IIPSocket conn, BitStream r) { var account = TryGetAccount(conn); if (account == null) return; User user; if ((user = TryGetUser(conn)) == null) return; string FriendsString = account.Friends; List<string> FriendsList = FriendsString.Split(',').ToList<string>(); string OnlineFriendsString = ""; string FriendsMap = ""; var OnlineMembers = Server.World.GetUsers(); foreach (var Member in OnlineMembers) { if (FriendsList.Contains(Member.Name)) { OnlineFriendsString += Member.Name + ","; var parentMap = World.GetMap(Member.Map.ParentMapID); FriendsMap += parentMap.Name + ","; } } using (var pw = ServerPacket.ReceiveFriends(OnlineFriendsString, FriendsMap, FriendsString)) { user.Send(pw, ServerMessageType.GUI); } }
void RecvStopShopping(IIPSocket conn, BitStream r) { GameplayScreen.ShopForm.HideShop(); }
void RecvSaveFriends(IIPSocket conn, BitStream r) { var account = TryGetAccount(conn); if (account == null) return; account.SetFriends(r.ReadString()); }
void RecvEndChatDialog(IIPSocket conn, BitStream r) { GameplayScreen.ChatDialogForm.EndDialog(); }
void RecvGetOnlineUsers(IIPSocket conn, BitStream r) { User myUser; if ((myUser = TryGetUser(conn)) == null) return; var allUsers = Server.World.GetUsers(); var orderedUsers = allUsers.OrderBy(x => !x.Permissions.IsSet(UserPermissions.None)).ThenBy(x => x.Name).ToList(); string onlineUsers = string.Empty; foreach (var user in orderedUsers) { if (myUser == user) continue; onlineUsers += user.Name + ";"; } using (var pw = ServerPacket.ReceiveAllUsers(onlineUsers)) { myUser.Send(pw, ServerMessageType.GUI); } }
/// <summary> /// When overridden in the derived class, allows for handling when the status of an <see cref="IIPSocket"/> changes. /// </summary> /// <param name="sender">The <see cref="IIPSocket"/> who's status has changed.</param> /// <param name="status">The new status.</param> /// <param name="reason">The reason for the status change.</param> protected override void OnReceiveStatusChanged(IIPSocket sender, NetConnectionStatus status, string reason) { base.OnReceiveStatusChanged(sender, status, reason); switch (status) { case NetConnectionStatus.Disconnected: // If there was an account on the socket, destroy it var acc = World.GetUserAccount(sender, false); if (acc != null) acc.Dispose(); break; case NetConnectionStatus.Connected: // Send the server time to the client using (var pw = ServerPacket.SetGameTime(DateTime.Now)) { sender.Send(pw, ServerMessageType.GUI); } break; } }
void RecvChat(IIPSocket conn, BitStream r) { var text = r.ReadString(GameData.MaxServerSayLength); GameplayScreen.AppendToChatOutput(text); }
/// <summary> /// Attempts to connects to the server. /// </summary> /// <param name="host">The server address.</param> /// <param name="port">The server port.</param> /// <param name="approvalMessage">The initial message to send to the server when making the connection. This can /// be utilized by the server to provide additional information for determining whether or not to accept the connection. /// Or, can be null to send nothing.</param> /// <returns> /// True if the connection attempt was successfully started. Does not mean that the connection was established, but /// just that it can be attempted. Will return false if a connection is already established or being established. /// </returns> public bool Connect(string host, int port, BitStream approvalMessage = null) { if (_local.ConnectionsCount > 0) return false; NetConnection conn; if (approvalMessage != null && approvalMessage.LengthBits > 0) { // Connect with approval message var netOutMsg = SocketHelper.GetNetOutgoingMessage(_local, approvalMessage.LengthBytes); approvalMessage.CopyTo(netOutMsg); conn = _local.Connect(host, port, netOutMsg); } else { // Connect without approval message conn = _local.Connect(host, port); } // Check if connection successful if (conn == null) { Debug.Fail("conn is null. Why?"); return false; } // Store the remote connection as an IPSocket _remote = IPSocket.Create(conn); return true; }
void RecvGroupInfo(IIPSocket conn, BitStream r) { GroupInfo.Read(r); }
void RecvCharAttack(IIPSocket conn, BitStream r) { // Read the values var attackerID = r.ReadMapEntityIndex(); MapEntityIndex?attackedID; if (r.ReadBool()) { attackedID = r.ReadMapEntityIndex(); } else { attackedID = null; } ActionDisplayID?actionDisplayIDNullable; if (r.ReadBool()) { actionDisplayIDNullable = r.ReadActionDisplayID(); } else { actionDisplayIDNullable = null; } // Get the object references using the IDs provided var attacker = _objGrabber.GetDynamicEntity <Character>(attackerID); if (attacker == null) { return; } DynamicEntity attacked; if (attackedID.HasValue) { attacked = Map.GetDynamicEntity(attackedID.Value); } else { attacked = null; } // Use the default ActionDisplayID if we were provided with a null value ActionDisplayID actionDisplayID; if (!actionDisplayIDNullable.HasValue) { actionDisplayID = GameData.DefaultActionDisplayID; } else { actionDisplayID = actionDisplayIDNullable.Value; } // Get the ActionDisplay to use and, if valid, execute it var actionDisplay = ActionDisplayScripts.ActionDisplays[actionDisplayID]; if (actionDisplay != null) { actionDisplay.Execute(Map, attacker, attacked); } }