private void PacketHandler_0x10_ClientJoin(Client client, ClientPacket packet) { var seed = packet.ReadByte(); var keyLength = packet.ReadByte(); var key = packet.Read(keyLength); var name = packet.ReadString8(); var id = packet.ReadUInt32(); var redirect = ExpectedConnections[id]; if (redirect.Matches(name, key, seed)) { ((IDictionary)ExpectedConnections).Remove(id); client.EncryptionKey = key; client.EncryptionSeed = seed; if (redirect.Source is Lobby) { var x60 = new ServerPacket(0x60); x60.WriteByte(0x00); x60.WriteUInt32(Game.NotificationCrc); client.Enqueue(x60); } } }
private void PacketHandler_0x10_ClientJoin(Client client, ClientPacket packet) { var seed = packet.ReadByte(); var keyLength = packet.ReadByte(); var key = packet.Read(keyLength); var name = packet.ReadString8(); var id = packet.ReadUInt32(); var redirect = ExpectedConnections[id]; if (Game.World.WorldData.TryGetAuthInfo(name, out AuthInfo login)) { login.CurrentState = UserState.Login; login.Save(); } if (redirect.Matches(name, key, seed)) { ((IDictionary)ExpectedConnections).Remove(id); client.EncryptionKey = key; client.EncryptionSeed = seed; if (redirect.Source is Lobby || redirect.Source is World) { var x60 = new ServerPacket(0x60); x60.WriteByte(0x00); x60.WriteUInt32(Game.NotificationCrc); client.Enqueue(x60); } } }
private void PacketHandler_0x57_ServerTable(Client client, ClientPacket packet) { var mismatch = packet.ReadByte(); if (mismatch == 1) { var x56 = new ServerPacket(0x56); x56.WriteUInt16((ushort)Game.ServerTable.Length); x56.Write(Game.ServerTable); client.Enqueue(x56); } else { var server = packet.ReadByte(); var redirect = new Redirect(client, this, Game.Login, "socket", client.EncryptionSeed, client.EncryptionKey); client.Redirect(redirect); } }
private void PacketHandler_0x57_ServerTable(Client client, ClientPacket packet) { var mismatch = packet.ReadByte(); if (mismatch == 1) { var x56 = new ServerPacket(0x56); x56.WriteUInt16((ushort)Game.ServerTable.Length); x56.Write(Game.ServerTable); Logger.InfoFormat("ServerTable: Sent: {0}", BitConverter.ToString(x56.ToArray())); client.Enqueue(x56); } else { var server = packet.ReadByte(); var redirect = new Redirect(client, this, Game.Login, "socket", client.EncryptionSeed, client.EncryptionKey); client.Redirect(redirect); } }
private void PacketHandler_0x04_CreateB(Client client, ClientPacket packet) { if (string.IsNullOrEmpty(client.NewCharacterName) || string.IsNullOrEmpty(client.NewCharacterPassword)) return; var hairStyle = packet.ReadByte(); var sex = packet.ReadByte(); var hairColor = packet.ReadByte(); if (hairStyle < 1) hairStyle = 1; if (hairStyle > 17) hairStyle = 17; if (hairColor > 13) hairColor = 13; if (sex < 1) sex = 1; if (sex > 2) sex = 2; if (!Game.World.PlayerExists(client.NewCharacterName)) { var newPlayer = new User(); newPlayer.Name = client.NewCharacterName; newPlayer.Sex = (Sex) sex; newPlayer.Location.Direction = Direction.South; newPlayer.Location.MapId = 136; newPlayer.Location.X = 10; newPlayer.Location.Y = 10; newPlayer.HairColor = hairColor; newPlayer.HairStyle = hairStyle; newPlayer.Class = Class.Peasant; newPlayer.Level = 1; newPlayer.Experience = 1; newPlayer.Level = 1; newPlayer.Experience = 0; newPlayer.AbilityExp = 0; newPlayer.Gold = 0; newPlayer.Ability = 0; newPlayer.Hp = 50; newPlayer.Mp = 50; newPlayer.BaseHp = 50; newPlayer.BaseMp = 50; newPlayer.BaseStr = 3; newPlayer.BaseInt = 3; newPlayer.BaseWis = 3; newPlayer.BaseCon = 3; newPlayer.BaseDex = 3; newPlayer.Login.CreatedTime = DateTime.Now; newPlayer.Password.Hash = client.NewCharacterPassword; newPlayer.Password.LastChanged = DateTime.Now; newPlayer.Password.LastChangedFrom = ((IPEndPoint) client.Socket.RemoteEndPoint).Address.ToString(); IDatabase cache = World.DatastoreConnection.GetDatabase(); var myPerson = JsonConvert.SerializeObject(newPlayer); cache.Set(String.Format("{0}:{1}", User.DatastorePrefix, newPlayer.Name), myPerson); // Logger.ErrorFormat("Error saving new player!"); // Logger.ErrorFormat(e.ToString()); // client.LoginMessage("Unknown error. Contact [email protected]", 3); // } client.LoginMessage("\0", 0); } }
private void PacketHandler_0x10_ClientJoin(Object obj, ClientPacket packet) { var connectionId = (long) obj; var seed = packet.ReadByte(); var keyLength = packet.ReadByte(); var key = packet.Read(keyLength); var name = packet.ReadString8(); var id = packet.ReadUInt32(); var redirect = ExpectedConnections[id]; if (redirect.Matches(name, key, seed)) { ((IDictionary) ExpectedConnections).Remove(id); if (PlayerExists(name)) { var user = new User(this, connectionId, name); user.SetEncryptionParameters(key, seed, name); user.LoadDataFromEntityFramework(true); user.UpdateLoginTime(); user.UpdateAttributes(StatUpdateFlags.Full); Logger.DebugFormat("Elapsed time since login: {0}", user.SinceLastLogin); if (user.Citizenship.spawn_points.Count != 0 && user.SinceLastLogin > Hybrasyl.Constants.NATION_SPAWN_TIMEOUT) { Insert(user); var spawnpoint = user.Citizenship.spawn_points.First(); user.Teleport((ushort) spawnpoint.map_id, (byte) spawnpoint.map_x, (byte) spawnpoint.map_y); } else if (user.MapId != null && Maps.ContainsKey(user.MapId)) { Insert(user); user.Teleport(user.MapId, (byte) user.MapX, (byte) user.MapY); } else { // Handle any weird cases where a map someone exited on was deleted, etc // This "default" of Mileth should be set somewhere else Insert(user); user.Teleport((ushort) 500, (byte) 50, (byte) 50); } Logger.DebugFormat("Adding {0} to hash", user.Name); AddUser(user); ActiveUsers[connectionId] = user; ActiveUsersByName[user.Name] = connectionId; Logger.InfoFormat("cid {0}: {1} entering world", connectionId, user.Name); } } }
private void PacketHandler_0x11_Turn(Object obj, ClientPacket packet) { var user = (User) obj; var direction = packet.ReadByte(); if (direction > 3) return; user.Turn((Direction) direction); }
private void PacketHandler_0x04_CreateB(Client client, ClientPacket packet) { if (string.IsNullOrEmpty(client.NewCharacterName) || string.IsNullOrEmpty(client.NewCharacterPassword)) return; var hairStyle = packet.ReadByte(); var sex = packet.ReadByte(); var hairColor = packet.ReadByte(); if (hairStyle < 1) hairStyle = 1; if (hairStyle > 17) hairStyle = 17; if (hairColor > 13) hairColor = 13; if (sex < 1) sex = 1; if (sex > 2) sex = 2; if (!Game.World.PlayerExists(client.NewCharacterName)) { using (var ctx = new hybrasylEntities(Constants.ConnectionString)) { player newplayer = new player { name = client.NewCharacterName, password_hash = client.NewCharacterPassword, sex = (Sex) sex, hairstyle = hairStyle, haircolor = hairColor, map_id = 136, map_x = 10, map_y = 10, direction = 1, class_type = 0, level = 1, exp = 0, ab = 0, gold = 0, ab_exp = 0, max_hp = 50, max_mp = 50, cur_hp = 50, cur_mp = 35, str = 3, @int = 3, wis = 3, con = 3, dex = 3, inventory = "[]", equipment = "[]", created_at = DateTime.Now }; try { ctx.players.Add(newplayer); ctx.SaveChanges(); } catch (Exception e) { Logger.ErrorFormat("Error saving new player!"); Logger.ErrorFormat(e.ToString()); client.LoginMessage("Unknown error. Contact [email protected]", 3); } client.LoginMessage("\0", 0); } } }
private void MerchantMenuHandler_SellItemWithQuantity(User user, Merchant merchant, ClientPacket packet) { packet.ReadByte(); byte slot = packet.ReadByte(); string qStr = packet.ReadString8(); int quantity; if (!int.TryParse(qStr, out quantity) || quantity < 1) { user.ShowSellQuantity(merchant, slot); return; } var item = user.Inventory[slot]; if (item == null || !item.Stackable) return; if (!merchant.Inventory.ContainsKey(item.Name)) { user.ShowMerchantGoBack(merchant, "I do not want that item.", MerchantMenuItem.SellItemMenu); return; } if (item.Count < quantity) { user.ShowMerchantGoBack(merchant, "You don't have that many to sell.", MerchantMenuItem.SellItemMenu); return; } user.ShowSellConfirm(merchant, slot, quantity); }
private void PacketHandler_0x07_PickupItem(Object obj, ClientPacket packet) { var user = (User) obj; var slot = packet.ReadByte(); var x = packet.ReadInt16(); var y = packet.ReadInt16(); //var user = client.User; //var map = user.Map; // Is the player within PICKUP_DISTANCE tiles of what they're trying to pick up? if (Math.Abs(x - user.X) > Constants.PICKUP_DISTANCE || Math.Abs(y - user.Y) > Constants.PICKUP_DISTANCE) return; // Check if inventory slot is valid and empty if (slot == 0 || slot > user.Inventory.Size || user.Inventory[slot] != null) return; // Find the items that are at the pickup area var tile = new Rectangle(x, y, 1, 1); // We don't want to pick up people var pickupObject = user.Map.EntityTree.GetObjects(tile).FindLast(i => i is Gold || i is Item); // If the add is successful, remove the item from the map quadtree if (pickupObject is Gold) { var gold = (Gold) pickupObject; if (user.AddGold(gold)) { Logger.DebugFormat("Removing {0}, qty {1} from {2}@{3},{4}", gold.Name, gold.Amount, user.Map.Name, x, y); user.Map.RemoveGold(gold); } } else if (pickupObject is Item) { var item = (Item) pickupObject; if (item.Stackable && user.Inventory.Contains(item.TemplateId)) { byte existingSlot = user.Inventory.SlotOf(item.TemplateId); var existingItem = user.Inventory[existingSlot]; int maxCanGive = existingItem.MaximumStack - existingItem.Count; int quantity = Math.Min(item.Count, maxCanGive); item.Count -= quantity; existingItem.Count += quantity; Logger.DebugFormat("Removing {0}, qty {1} from {2}@{3},{4}", item.Name, item.Count, user.Map.Name, x, y); user.Map.Remove(item); user.SendItemUpdate(existingItem, existingSlot); if (item.Count == 0) Remove(item); else { user.Map.Insert(item, user.X, user.Y); user.SendMessage(string.Format("You can't carry any more {0}.", item.Name), 3); } } else { Logger.DebugFormat("Removing {0}, qty {1} from {2}@{3},{4}", item.Name, item.Count, user.Map.Name, x, y); user.Map.Remove(item); user.AddItem(item, slot); } } }
private void PacketHandler_0x47_StatPoint(Object obj, ClientPacket packet) { var user = (User) obj; if (user.LevelPoints > 0) { switch (packet.ReadByte()) { case 0x01: user.BaseStr++; break; case 0x04: user.BaseInt++; break; case 0x08: user.BaseWis++; break; case 0x10: user.BaseCon++; break; case 0x02: user.BaseDex++; break; default: return; } user.LevelPoints--; user.UpdateAttributes(StatUpdateFlags.Primary); } }
private void PacketHandler_0x79_Status(Object obj, ClientPacket packet) { var user = (User) obj; var status = packet.ReadByte(); if (status <= 7) { user.GroupStatus = (UserStatus) status; } }
private void PacketHandler_0x44_EquippedItemClick(Object obj, ClientPacket packet) { var user = (User) obj; // This packet is received when a client unequips an item from the detail (a) screen. var slot = packet.ReadByte(); Logger.DebugFormat("Removing equipment from slot {0}", slot); var item = user.Equipment[slot]; if (item != null) { Logger.DebugFormat("actually removing item"); user.RemoveEquipment(slot); // Add our removed item to our first empty inventory slot Logger.DebugFormat("Player weight is currently {0}", user.CurrentWeight); Logger.DebugFormat("Adding item {0}, count {1} to inventory", item.Name, item.Count); user.AddItem(item); Logger.DebugFormat("Player weight is now {0}", user.CurrentWeight); } else { Logger.DebugFormat("Ignoring useless click on slot {0}", slot); return; } }
private void PacketHandler_0x0B_ClientExit(Object obj, ClientPacket packet) { var user = (User) obj; var endSignal = packet.ReadByte(); if (endSignal == 1) { var x4C = new ServerPacket(0x4C); x4C.WriteByte(0x01); x4C.WriteUInt16(0x00); user.Enqueue(x4C); } else { long connectionId; user.Save(); user.UpdateLogoffTime(); user.Map.Remove(user); Remove(user); DeleteUser(user.Name); user.SendRedirectAndLogoff(this, Game.Login, user.Name); if (ActiveUsersByName.TryRemove(user.Name, out connectionId)) { ((IDictionary) ActiveUsers).Remove(connectionId); } Logger.InfoFormat("cid {0}: {1} leaving world", connectionId, user.Name); } }
private void PacketHandler_0x0E_Talk(Object obj, ClientPacket packet) { var user = (User) obj; var isShout = packet.ReadByte(); var message = packet.ReadString8(); if (message.StartsWith("/")) { var args = message.Split(' '); #region world's biggest switch statement switch (args[0].ToLower()) { case "/gold": { uint amount; if (args.Length != 2 || !uint.TryParse(args[1], out amount)) break; user.Gold = amount; user.UpdateAttributes(StatUpdateFlags.Experience); } break; case "/summon": { if (!user.IsPrivileged) return; if (args.Length == 2) { if (!Users.ContainsKey(args[1])) { user.SendMessage("User not logged in.", MessageTypes.SYSTEM); return; } var target = Users[args[1]]; if (target.IsExempt) user.SendMessage("Access denied.", MessageTypes.SYSTEM); else { target.Teleport(user.Map.Id, user.MapX, user.MapY); Logger.InfoFormat("GM activity: {0} summoned {1}", user.Name, target.Name); } } } break; case "/kick": { if (!user.IsPrivileged) return; if (args.Length == 2) { if (!Users.ContainsKey(args[1])) { user.SendMessage("User not logged in.", MessageTypes.SYSTEM); return; } var target = Users[args[1]]; if (target.IsExempt) user.SendMessage("Access denied.", MessageTypes.SYSTEM); else target.Logoff(); Logger.InfoFormat("GM activity: {0} kicked {1}", user.Name, target.Name); } } break; case "/teleport": { ushort number = ushort.MaxValue; byte x = user.X, y = user.Y; if (args.Length == 2) { if (!ushort.TryParse(args[1], out number)) { if (!Users.ContainsKey(args[1])) { user.SendMessage("Invalid map number or user name", 3); return; } else { var target = Users[args[1]]; number = target.Map.Id; x = target.X; y = target.Y; } } } else if (args.Length == 4) { ushort.TryParse(args[1], out number); byte.TryParse(args[2], out x); byte.TryParse(args[3], out y); } if (Maps.ContainsKey(number)) { var map = Maps[number]; if (x < map.X && y < map.Y) user.Teleport(number, x, y); else user.SendMessage("Invalid x/y", 3); } else user.SendMessage("Invalid map number", 3); } break; case "/motion": { byte motion; short speed = 20; if (args.Length > 1 && byte.TryParse(args[1], out motion)) { if (args.Length > 2) short.TryParse(args[2], out speed); user.Motion(motion, speed); } } break; case "/maplist": { // This is an extremely expensive slash command var searchString = ""; if (args.Length == 1) { user.SendMessage("Usage: /maplist <searchterm>\nExample: /maplist Mileth - show maps with Mileth in the title\n", MessageTypes.SLATE); return; } else if (args.Length == 2) searchString = args[1]; else searchString = String.Join(" ", args, 1, args.Length - 1); Regex searchTerm; try { Logger.InfoFormat("Search term was {0}",searchString); searchTerm = new Regex(String.Format("{0}", searchString)); } catch { user.SendMessage("Invalid search. Try again or send no options for help.", MessageTypes.SYSTEM); return; } var queryMaps = from amap in MapCatalog where searchTerm.IsMatch(amap.Key) select amap; var result = queryMaps.Aggregate("", (current, map) => current + String.Format("{0} - {1}\n", map.Value.Id, map.Value.Name)); if (result.Length > 65400) result = String.Format("{0}\n(Results truncated)", result.Substring(0, 65400)); user.SendMessage(String.Format("Search Results\n---------------\n\n{0}", result), MessageTypes.SLATE_WITH_SCROLLBAR); } break; case "/effect": { ushort effect; short speed = 100; if (args.Length > 1 && ushort.TryParse(args[1], out effect)) { if (args.Length > 2) short.TryParse(args[2], out speed); user.Effect(effect, speed); } } break; case "/sound": { byte sound; if (args.Length > 1 && byte.TryParse(args[1], out sound)) { user.SendSound(sound); } } break; case "/music": { byte track; if (args.Length > 1 && byte.TryParse(args[1], out track)) { user.Map.Music = track; foreach (var mapuser in user.Map.Users.Values) { mapuser.SendMusic(track); } } } break; case "/mapmsg": { if (args.Length > 1) { var mapmsg = string.Join(" ", args, 1, args.Length - 1); user.Map.Message = mapmsg; foreach (var mapuser in user.Map.Users.Values) { mapuser.SendMessage(mapmsg, 18); } } } break; case "/worldmsg": { if (args.Length > 1) { var msg = string.Join(" ", args, 1, args.Length - 1); foreach (var connectedUser in ActiveUsers) { connectedUser.Value.SendWorldMessage(user.Name, msg); } } } break; case "/class": { var className = string.Join(" ", args, 1, args.Length - 1); int classValue; if (Hybrasyl.Constants.CLASSES.TryGetValue(className, out classValue)) { user.Class = (Hybrasyl.Enums.Class) Hybrasyl.Constants.CLASSES[className]; user.SendMessage(String.Format("Class set to {0}", className.ToLower()), 0x1); } else { user.SendMessage("I know nothing about that class. Try again.", 0x1); } } break; case "/level": { byte newLevel; var level = string.Join(" ", args, 1, args.Length - 1); if (!Byte.TryParse(level, out newLevel)) user.SendMessage("That's not a valid level, champ.", 0x1); else { user.Level = newLevel; user.UpdateAttributes(StatUpdateFlags.Full); user.SendMessage(String.Format("Level changed to {0}", newLevel), 0x1); } } break; case "/attr": { if (args.Length != 3) { return; } byte newStat; if (!Byte.TryParse(args[2], out newStat)) { user.SendSystemMessage("That's not a valid value for an attribute, chief."); return; } switch (args[1].ToLower()) { case "str": user.BaseStr = newStat; break; case "con": user.BaseCon = newStat; break; case "dex": user.BaseDex = newStat; break; case "wis": user.BaseWis = newStat; break; case "int": user.BaseInt = newStat; break; default: user.SendSystemMessage("Invalid attribute, sport."); break; } user.UpdateAttributes(StatUpdateFlags.Stats); } break; case "/guild": { var guild = string.Join(" ", args, 1, args.Length - 1); user.Guild = guild; user.SendMessage(String.Format("Guild changed to {0}", guild), 0x1); } break; case "/guildrank": { var guildrank = string.Join(" ", args, 1, args.Length - 1); user.GuildRank = guildrank; user.SendMessage(String.Format("Guild rank changed to {0}", guildrank), 0x1); } break; case "/title": { var title = string.Join(" ", args, 1, args.Length - 1); user.Title = title; user.SendMessage(String.Format("Title changed to {0}", title), 0x1); } break; case "/debug": { if (!user.IsPrivileged) return; user.SendMessage("Debugging enabled", 3); ((log4net.Repository.Hierarchy.Hierarchy) LogManager.GetRepository()).Root.Level = Level.Debug; ((log4net.Repository.Hierarchy.Hierarchy) LogManager.GetRepository()).RaiseConfigurationChanged( EventArgs.Empty); Logger.InfoFormat("Debugging enabled by admin command"); } break; case "/nodebug": { if (!user.IsPrivileged) return; user.SendMessage("Debugging disabled", 3); ((log4net.Repository.Hierarchy.Hierarchy) LogManager.GetRepository()).Root.Level = Level.Info; ((log4net.Repository.Hierarchy.Hierarchy) LogManager.GetRepository()).RaiseConfigurationChanged( EventArgs.Empty); Logger.InfoFormat("Debugging disabled by admin command"); } break; case "/gcm": { if (!user.IsPrivileged) return; var gcmContents = "Contents of Global Connection Manifest\n"; var userContents = "Contents of User Dictionary\n"; var ActiveUserContents = "Contents of ActiveUsers Concurrent Dictionary\n"; foreach (var pair in GlobalConnectionManifest.ConnectedClients) { var serverType = String.Empty; switch (pair.Value.ServerType) { case ServerTypes.Lobby: serverType = "Lobby"; break; case ServerTypes.Login: serverType = "Login"; break; default: serverType = "World"; break; } try { gcmContents = gcmContents + String.Format("{0}:{1} - {2}:{3}\n", pair.Key, ((IPEndPoint) pair.Value.Socket.RemoteEndPoint).Address.ToString(), ((IPEndPoint) pair.Value.Socket.RemoteEndPoint).Port, serverType); } catch { gcmContents = gcmContents + String.Format("{0}:{1} disposed\n", pair.Key, serverType); } } foreach (var tehuser in Users) { userContents = userContents + tehuser.Value.Name + "\n"; } foreach (var tehotheruser in ActiveUsersByName) { ActiveUserContents = ActiveUserContents + String.Format("{0}: {1}\n", tehotheruser.Value, tehotheruser.Key); } // Report to the end user user.SendMessage( String.Format("{0}\n\n{1}\n\n{2}", gcmContents, userContents, ActiveUserContents), MessageTypes.SLATE_WITH_SCROLLBAR); } break; case "/item": { int count; string itemName; Logger.DebugFormat("/item: Last argument is {0}", args.Last()); Regex integer = new Regex(@"^\d+$"); if (integer.IsMatch(args.Last())) { count = Convert.ToInt32(args.Last()); itemName = string.Join(" ", args, 1, args.Length - 2); Logger.InfoFormat("Admin command: Creating item {0} with count {1}", itemName, count); } else { count = 1; itemName = string.Join(" ", args, 1, args.Length - 1); } // HURR O(N) IS MY FRIEND // change this to use itemcatalog pls foreach (var template in Items) { if (template.Value.name.Equals(itemName, StringComparison.CurrentCultureIgnoreCase)) { var item = CreateItem(template.Key); if (count > item.MaximumStack) item.Count = item.MaximumStack; else item.Count = count; Insert(item); user.AddItem(item); } } } break; case "/mute": { if (!user.IsPrivileged) return; var charTarget = string.Join(" ", args, 1, args.Length - 1); var userObj = FindUser(charTarget); if (userObj != null) { userObj.IsMuted = true; userObj.Save(); user.SendMessage(String.Format("{0} is now muted.", userObj.Name), 0x1); } else { user.SendMessage("That Aisling is not in Temuair.", 0x01); } } break; case "/unmute": { if (!user.IsPrivileged) return; var charTarget = string.Join(" ", args, 1, args.Length - 1); var userObj = FindUser(charTarget); if (userObj != null) { userObj.IsMuted = false; userObj.Save(); user.SendMessage(String.Format("{0} is now unmuted.", userObj.Name), 0x1); } else { user.SendMessage("That Aisling is not in Temuair.", 0x01); } } break; case "/reload": { if (!user.IsPrivileged) return; // Do nothing here for now // This should reload warps, worldwarps, "item templates", worldmaps, and world map points. // This should obviously use the new ControlMessage stuff. user.SendMessage("This feature is not currently implemented.", 0x01); } break; case "/shutdown": { if (!user.IsPrivileged) return; var password = args[1]; if (String.Equals(password, Constants.ShutdownPassword)) { MessageQueue.Add(new HybrasylControlMessage(ControlOpcodes.ShutdownServer, user.Name)); } } break; case "/scripting": { if (!user.IsPrivileged) return; // Valid scripting commands // /scripting (reload|disable|enable|status) [scriptname] if (args.Count() >= 3) { var script = ScriptProcessor.GetScript(args[2].Trim()); if (script != null) { if (args[1].ToLower() == "reload") { script.Disabled = true; if (script.Load()) { user.SendMessage(String.Format("Script {0}: reloaded", script.Name), 0x01); if (script.InstantiateScriptable()) user.SendMessage( String.Format("Script {0}: instances recreated", script.Name), 0x01); } else { user.SendMessage( String.Format("Script {0}: load error, consult status", script.Name), 0x01); } } else if (args[1].ToLower() == "enable") { script.Disabled = false; user.SendMessage(String.Format("Script {0}: enabled", script.Name), 0x01); } else if (args[1].ToLower() == "disable") { script.Disabled = true; user.SendMessage(String.Format("Script {0}: disabled", script.Name), 0x01); } else if (args[1].ToLower() == "status") { var scriptStatus = String.Format("{0}:", script.Name); String errorSummary = "--- Error Summary ---\n"; if (script.Instance == null) scriptStatus = String.Format("{0} not instantiated,", scriptStatus); else scriptStatus = String.Format("{0} instantiated,", scriptStatus); if (script.Disabled) scriptStatus = String.Format("{0} disabled", scriptStatus); else scriptStatus = String.Format("{0} enabled", scriptStatus); if (script.LastRuntimeError == String.Empty && script.CompilationError == String.Empty) errorSummary = String.Format("{0} no errors", errorSummary); else { if (script.CompilationError != String.Empty) errorSummary = String.Format("{0} compilation error: {1}", errorSummary, script.CompilationError); if (script.LastRuntimeError != String.Empty) errorSummary = String.Format("{0} runtime error: {1}", errorSummary, script.LastRuntimeError); } // Report to the end user user.SendMessage(String.Format("{0}\n\n{1}", scriptStatus, errorSummary), MessageTypes.SLATE_WITH_SCROLLBAR); } } else { user.SendMessage(String.Format("Script {0} not found!", args[2]), 0x01); } } else if (args.Count() == 2) { if (args[1].ToLower() == "status") { // Display status information for all NPCs String statusReport = String.Empty; String errorSummary = "--- Error Summary ---\n"; foreach (KeyValuePair<string, Script> entry in ScriptProcessor.Scripts) { var scriptStatus = String.Format("{0}:", entry.Key); var scriptErrors = String.Format("{0}:", entry.Key); if (entry.Value.Instance == null) scriptStatus = String.Format("{0} not instantiated,", scriptStatus); else scriptStatus = String.Format("{0} instantiated,", scriptStatus); if (entry.Value.Disabled) scriptStatus = String.Format("{0} disabled", scriptStatus); else scriptStatus = String.Format("{0} enabled", scriptStatus); if (entry.Value.LastRuntimeError == String.Empty && entry.Value.CompilationError == String.Empty) scriptErrors = String.Format("{0} no errors", scriptErrors); else { if (entry.Value.CompilationError != String.Empty) scriptErrors = String.Format("{0} compilation error: {1}", scriptErrors, entry.Value.CompilationError); if (entry.Value.LastRuntimeError != String.Empty) scriptErrors = String.Format("{0} runtime error: {1}", scriptErrors, entry.Value.LastRuntimeError); } statusReport = String.Format("{0}\n{1}", statusReport, scriptStatus); errorSummary = String.Format("{0}\n{1}", errorSummary, scriptErrors); } // Report to the end user user.SendMessage(String.Format("{0}\n\n{1}", statusReport, errorSummary), MessageTypes.SLATE_WITH_SCROLLBAR); } } } break; #endregion world's biggest switch statement } } else { if (user.CheckSquelch(0x0e, message)) { Logger.DebugFormat("{1}: squelched (say/shout)", user.Name); return; } if (isShout == 1) { user.Shout(message); } else { user.Say(message); } } }
private void PacketHandler_0x04_CreateB(Client client, ClientPacket packet) { if (string.IsNullOrEmpty(client.NewCharacterName) || string.IsNullOrEmpty(client.NewCharacterPassword)) { return; } var hairStyle = packet.ReadByte(); var sex = packet.ReadByte(); var hairColor = packet.ReadByte(); if (hairStyle < 1) { hairStyle = 1; } if (hairStyle > 17) { hairStyle = 17; } if (hairColor > 13) { hairColor = 13; } if (sex < 1) { sex = 1; } if (sex > 2) { sex = 2; } if (!Game.World.PlayerExists(client.NewCharacterName)) { using (var ctx = new hybrasylEntities(Constants.ConnectionString)) { player newplayer = new player { name = client.NewCharacterName, password_hash = client.NewCharacterPassword, sex = (Sex)sex, hairstyle = hairStyle, haircolor = hairColor, map_id = 136, map_x = 10, map_y = 10, direction = 1, class_type = 0, level = 1, exp = 0, ab = 0, gold = 0, ab_exp = 0, max_hp = 50, max_mp = 50, cur_hp = 50, cur_mp = 35, str = 3, @int = 3, wis = 3, con = 3, dex = 3, inventory = "[]", equipment = "[]", created_at = DateTime.Now }; try { ctx.players.Add(newplayer); ctx.SaveChanges(); } catch (Exception e) { Logger.ErrorFormat("Error saving new player!"); Logger.ErrorFormat(e.ToString()); client.LoginMessage("Unknown error. Contact [email protected]", 3); } client.LoginMessage("\0", 0); } } }
private void PacketHandler_0x04_CreateB(Client client, ClientPacket packet) { if (string.IsNullOrEmpty(client.NewCharacterName) || string.IsNullOrEmpty(client.NewCharacterPassword)) { return; } var hairStyle = packet.ReadByte(); var gender = packet.ReadByte(); var hairColor = packet.ReadByte(); if (hairStyle < 1) { hairStyle = 1; } if (hairStyle > 17) { hairStyle = 17; } if (hairColor > 13) { hairColor = 13; } if (gender < 1) { gender = 1; } if (gender > 2) { gender = 2; } // Try to get our map // TODO: replace with XML config for start map, x, y Map map; if (!Game.World.WorldData.TryGetValue(136, out map)) { map = Game.World.WorldData.GetDictionary <Map>().First().Value; } if (!World.PlayerExists(client.NewCharacterName)) { var newPlayer = new User(); newPlayer.Uuid = Guid.NewGuid().ToString(); newPlayer.Name = client.NewCharacterName; newPlayer.Gender = (Xml.Gender)gender; newPlayer.Location.Direction = Xml.Direction.South; newPlayer.Location.Map = map; newPlayer.Location.X = 10; newPlayer.Location.Y = 10; newPlayer.HairColor = hairColor; newPlayer.HairStyle = hairStyle; newPlayer.Class = Xml.Class.Peasant; newPlayer.Gold = 0; newPlayer.Login.CreatedTime = DateTime.Now; newPlayer.Login.FirstLogin = true; newPlayer.Password.Hash = client.NewCharacterPassword; newPlayer.Password.LastChanged = DateTime.Now; newPlayer.Password.LastChangedFrom = ((IPEndPoint)client.Socket.RemoteEndPoint).Address.ToString(); newPlayer.Nation = Game.World.DefaultNation; IDatabase cache = World.DatastoreConnection.GetDatabase(); cache.Set(User.GetStorageKey(newPlayer.Name), newPlayer); var vault = new Vault(newPlayer.Uuid); vault.Save(); var parcelStore = new ParcelStore(newPlayer.Uuid); parcelStore.Save(); client.LoginMessage("\0", 0); } }
private void PacketHandler_0x45_ByteHeartbeat(object obj, ClientPacket packet) { var user = (User) obj; // Client sends 0x45 response in the reverse order of what the server sends... var byteB = packet.ReadByte(); var byteA = packet.ReadByte(); if (!user.IsHeartbeatValid(byteA, byteB)) { Logger.InfoFormat("{0}: byte heartbeat not valid, disconnecting", user.Name); user.Logoff(); } else { Logger.DebugFormat("{0}: byte heartbeat valid", user.Name); } }
private void PacketHandler_0x19_Whisper(Object obj, ClientPacket packet) { var user = (User) obj; var size = packet.ReadByte(); var target = Encoding.GetEncoding(949).GetString(packet.Read(size)); var msgsize = packet.ReadByte(); var message = Encoding.GetEncoding(949).GetString(packet.Read(msgsize)); user.SendWhisper(target, message); }
private void PacketHandler_0x4A_Trade(object obj, ClientPacket packet) { var user = (User) obj; var tradeStage = packet.ReadByte(); if (tradeStage == 0 && user.ActiveExchange != null) return; if (tradeStage != 0 && user.ActiveExchange == null) return; if (user.ActiveExchange != null && !user.ActiveExchange.ConditionsValid) return; switch (tradeStage) { case 0x00: { // Starting trade var x0PlayerId = packet.ReadInt32(); WorldObject target; if (Objects.TryGetValue((uint)x0PlayerId, out target)) { if (target is User) { var playerTarget = (User)target; if (Exchange.StartConditionsValid(user, playerTarget)) { user.SendMessage("That can't be done right now.", MessageTypes.SYSTEM); return; } // Initiate exchange var exchange = new Exchange(user, playerTarget); exchange.StartExchange(); } } } break; case 0x01: // Add item to trade { // We ignore playerId because we only allow one exchange at a time and we // keep track of the participants on both sides var x1playerId = packet.ReadInt32(); var x1ItemSlot = packet.ReadByte(); if (user.Inventory[x1ItemSlot] != null && user.Inventory[x1ItemSlot].Count > 1) { // Send quantity request user.SendExchangeQuantityPrompt(x1ItemSlot); } else user.ActiveExchange.AddItem(user, x1ItemSlot); } break; case 0x02: // Add item with quantity var x2PlayerId = packet.ReadInt32(); var x2ItemSlot = packet.ReadByte(); var x2ItemQuantity = packet.ReadByte(); user.ActiveExchange.AddItem(user, x2ItemSlot, x2ItemQuantity); break; case 0x03: // Add gold to trade var x3PlayerId = packet.ReadInt32(); var x3GoldQuantity = packet.ReadUInt32(); user.ActiveExchange.AddGold(user, x3GoldQuantity); break; case 0x04: // Cancel trade Logger.Debug("Cancelling trade"); user.ActiveExchange.CancelExchange(user); break; case 0x05: // Confirm trade Logger.Debug("Confirming trade"); user.ActiveExchange.ConfirmExchange(user); break; default: return; } }
private void PacketHandler_0x1C_UseItem(Object obj, ClientPacket packet) { var user = (User) obj; var slot = packet.ReadByte(); Logger.DebugFormat("Updating slot {0}", slot); if (slot == 0 || slot > Constants.MAXIMUM_INVENTORY) return; var item = user.Inventory[slot]; if (item == null) return; switch (item.ItemType) { case ItemType.CanUse: item.Invoke(user); break; case ItemType.CannotUse: user.SendMessage("You can't use that.", 3); break; case ItemType.Equipment: { // Check item requirements here before we do anything rash String message; if (!item.CheckRequirements(user, out message)) { // If an item can't be equipped, CheckRequirements will return false // and also set the appropriate message for us via out user.SendMessage(message, 3); return; } Logger.DebugFormat("Equipping {0}", item.Name); // Remove the item from inventory, but we don't decrement its count, as it still exists. user.RemoveItem(slot); // Handle gauntlet / ring special cases if (item.EquipmentSlot == ClientItemSlots.Gauntlet) { Logger.DebugFormat("item is gauntlets"); // First, is the left arm slot occupied? if (user.Equipment[ClientItemSlots.LArm] != null) { if (user.Equipment[ClientItemSlots.RArm] == null) { // Right arm slot is empty; use it user.AddEquipment(item, ClientItemSlots.RArm); } else { // Right arm slot is in use; replace LArm with item var olditem = user.Equipment[ClientItemSlots.LArm]; user.RemoveEquipment(ClientItemSlots.LArm); user.AddItem(olditem, slot); user.AddEquipment(item, ClientItemSlots.LArm); } } else { user.AddEquipment(item, ClientItemSlots.LArm); } } else if (item.EquipmentSlot == ClientItemSlots.Ring) { Logger.DebugFormat("item is ring"); // First, is the left ring slot occupied? if (user.Equipment[ClientItemSlots.LHand] != null) { if (user.Equipment[ClientItemSlots.RHand] == null) { // Right ring slot is empty; use it user.AddEquipment(item, ClientItemSlots.RHand); } else { // Right ring slot is in use; replace LHand with item var olditem = user.Equipment[ClientItemSlots.LHand]; user.RemoveEquipment(ClientItemSlots.LHand); user.AddItem(olditem, slot); user.AddEquipment(item, ClientItemSlots.LHand); } } else { user.AddEquipment(item, ClientItemSlots.LHand); } } else if (item.EquipmentSlot == ClientItemSlots.FirstAcc || item.EquipmentSlot == ClientItemSlots.SecondAcc || item.EquipmentSlot == ClientItemSlots.ThirdAcc) { if (user.Equipment.FirstAcc == null) user.AddEquipment(item, ClientItemSlots.FirstAcc); else if (user.Equipment.SecondAcc == null) user.AddEquipment(item, ClientItemSlots.SecondAcc); else if (user.Equipment.ThirdAcc == null) user.AddEquipment(item, ClientItemSlots.ThirdAcc); else { // Remove first accessory var oldItem = user.Equipment.FirstAcc; user.RemoveEquipment(ClientItemSlots.FirstAcc); user.AddEquipment(item, ClientItemSlots.FirstAcc); user.AddItem(oldItem, slot); user.Show(); } } else { var equipSlot = item.EquipmentSlot; var oldItem = user.Equipment[equipSlot]; if (oldItem != null) { Logger.DebugFormat(" Attemping to equip {0}", item.Name); Logger.DebugFormat("..which would unequip {0}", oldItem.Name); Logger.DebugFormat("Player weight is currently {0}", user.CurrentWeight); user.RemoveEquipment(equipSlot); user.AddItem(oldItem, slot); user.AddEquipment(item, equipSlot); user.Show(); Logger.DebugFormat("Player weight is currently {0}", user.CurrentWeight); } else { Logger.DebugFormat("Attemping to equip {0}", item.Name); user.AddEquipment(item, equipSlot); user.Show(); } } } break; } }
private void MerchantMenuHandler_SellItem(User user, Merchant merchant, ClientPacket packet) { byte slot = packet.ReadByte(); var item = user.Inventory[slot]; if (item == null) return; if (!merchant.Inventory.ContainsKey(item.Name)) { user.ShowMerchantGoBack(merchant, "I do not want that item.", MerchantMenuItem.SellItemMenu); return; } if (item.Stackable && item.Count > 1) { user.ShowSellQuantity(merchant, slot); return; } user.ShowSellConfirm(merchant, slot, 1); }
private void PacketHandler_0x1D_Emote(Object obj, ClientPacket packet) { var user = (User) obj; var emote = packet.ReadByte(); if (emote <= 35) { emote += 9; user.Motion(emote, 120); } }
private void MerchantMenuHandler_SellItemConfirmation(User user, Merchant merchant, ClientPacket packet) { packet.ReadByte(); byte slot = packet.ReadByte(); byte quantity = packet.ReadByte(); var item = user.Inventory[slot]; if (item == null) return; if (!merchant.Inventory.ContainsKey(item.Name)) { user.ShowMerchantGoBack(merchant, "I do not want that item.", MerchantMenuItem.SellItemMenu); return; } if (item.Count < quantity) { user.ShowMerchantGoBack(merchant, "You don't have that many to sell.", MerchantMenuItem.SellItemMenu); return; } uint profit = (uint) (Math.Round(item.Value*0.50)*quantity); if (item.Stackable && quantity < item.Count) user.DecreaseItem(slot, quantity); else user.RemoveItem(slot); user.AddGold(profit); merchant.DisplayPursuits(user); }
private void PacketHandler_0x29_DropItemOnCreature(Object obj, ClientPacket packet) { var itemSlot = packet.ReadByte(); var targetId = packet.ReadUInt32(); var quantity = packet.ReadByte(); var user = (User) obj; // If the object is a creature or an NPC, simply give them the item, otherwise, // initiate an exchange WorldObject target; if (!user.World.Objects.TryGetValue(targetId, out target)) return; if (user.Map.Objects.Contains((VisibleObject)target)) { if (target is User) { var playerTarget = (User) target; // Pre-flight checks if (!Exchange.StartConditionsValid(user, playerTarget)) { user.SendSystemMessage("You can't do that."); return; } if (!playerTarget.IsAvailableForExchange) { user.SendSystemMessage("They can't do that right now."); return; } if (!user.IsAvailableForExchange) { user.SendSystemMessage("You can't do that right now."); } // Initiate exchange and put item in it var exchange = new Exchange(user, playerTarget); exchange.StartExchange(); if (user.Inventory[itemSlot] != null && user.Inventory[itemSlot].Count > 1) user.SendExchangeQuantityPrompt(itemSlot); else exchange.AddItem(user, itemSlot, quantity); } else if (target is Creature && user.IsInViewport((VisibleObject)target)) { var creature = (Creature) target; var item = user.Inventory[itemSlot]; if (item != null) { if (user.RemoveItem(itemSlot)) { creature.Inventory.AddItem(item); } else Logger.WarnFormat("0x29: Couldn't remove item from inventory...?"); } } } }
private void PacketHandler_0x08_DropItem(Object obj, ClientPacket packet) { var user = (User) obj; var slot = packet.ReadByte(); var x = packet.ReadInt16(); var y = packet.ReadInt16(); var count = packet.ReadInt32(); Logger.DebugFormat("{0} {1} {2} {3}", slot, x, y, count); // Do a few sanity checks // // Is the distance valid? (Can't drop things beyond // MAXIMUM_DROP_DISTANCE tiles away) if (Math.Abs(x - user.X) > Constants.PICKUP_DISTANCE || Math.Abs(y - user.Y) > Constants.PICKUP_DISTANCE) { Logger.ErrorFormat("Request to drop item exceeds maximum distance {0}", Hybrasyl.Constants.MAXIMUM_DROP_DISTANCE); return; } // Is this a valid slot? if ((slot == 0) || (slot > Hybrasyl.Constants.MAXIMUM_INVENTORY)) { Logger.ErrorFormat("Slot not valid. Aborting"); return; } // Does the player actually have an item in the slot? Does the count in the packet exceed the // count in the player's inventory? Are they trying to drop the item on something that // is impassable (i.e. a wall)? if ((user.Inventory[slot] == null) || (count > user.Inventory[slot].Count) || (user.Map.IsWall[x, y] == true) || !user.Map.IsValidPoint(x, y)) { Logger.ErrorFormat( "Slot {0} is null, or count {1} exceeds count {2}, or {3},{4} is a wall, or {3},{4} is out of bounds", slot, count, user.Inventory[slot].Count, x, y); return; } Item toDrop = user.Inventory[slot]; if (toDrop.Stackable && count < toDrop.Count) { toDrop.Count -= count; user.SendItemUpdate(toDrop, slot); toDrop = new Item(toDrop); toDrop.Count = count; Insert(toDrop); } else { user.RemoveItem(slot); } // Are we dropping an item onto a reactor? Reactor reactor; var coordinates = new Tuple<byte, byte>((byte) x, (byte) y); if (user.Map.Reactors.TryGetValue(coordinates, out reactor)) { reactor.OnDrop(user, toDrop); } else user.Map.AddItem(x, y, toDrop); }
private void PacketHandler_0x30_MoveUIElement(Object obj, ClientPacket packet) { var user = (User) obj; var window = packet.ReadByte(); var oldSlot = packet.ReadByte(); var newSlot = packet.ReadByte(); var inventory = user.Inventory; // For right now we ignore the other cases (moving a skill or spell) if (window > 0) return; Logger.DebugFormat("Moving {0} to {1}", oldSlot, newSlot); // Is the slot invalid? Does at least one of the slots contain an item? if (oldSlot == 0 || oldSlot > Constants.MAXIMUM_INVENTORY || newSlot == 0 || newSlot > Constants.MAXIMUM_INVENTORY || (inventory[oldSlot] == null && inventory[newSlot] == null)) return; user.SwapItem(oldSlot, newSlot); }
private void PacketHandler_0x04_CreateB(Client client, ClientPacket packet) { if (string.IsNullOrEmpty(client.NewCharacterName) || string.IsNullOrEmpty(client.NewCharacterPassword)) { return; } var hairStyle = packet.ReadByte(); var sex = packet.ReadByte(); var hairColor = packet.ReadByte(); if (hairStyle < 1) { hairStyle = 1; } if (hairStyle > 17) { hairStyle = 17; } if (hairColor > 13) { hairColor = 13; } if (sex < 1) { sex = 1; } if (sex > 2) { sex = 2; } if (!Game.World.PlayerExists(client.NewCharacterName)) { var newPlayer = new User(); newPlayer.Name = client.NewCharacterName; newPlayer.Sex = (Sex)sex; newPlayer.Location.Direction = Direction.South; newPlayer.Location.MapId = 136; newPlayer.Location.X = 10; newPlayer.Location.Y = 10; newPlayer.HairColor = hairColor; newPlayer.HairStyle = hairStyle; newPlayer.Class = Class.Peasant; newPlayer.Level = 1; newPlayer.Experience = 1; newPlayer.Level = 1; newPlayer.Experience = 0; newPlayer.AbilityExp = 0; newPlayer.Gold = 0; newPlayer.Ability = 0; newPlayer.Hp = 50; newPlayer.Mp = 50; newPlayer.BaseHp = 50; newPlayer.BaseMp = 50; newPlayer.BaseStr = 3; newPlayer.BaseInt = 3; newPlayer.BaseWis = 3; newPlayer.BaseCon = 3; newPlayer.BaseDex = 3; newPlayer.Login.CreatedTime = DateTime.Now; newPlayer.Password.Hash = client.NewCharacterPassword; newPlayer.Password.LastChanged = DateTime.Now; newPlayer.Password.LastChangedFrom = ((IPEndPoint)client.Socket.RemoteEndPoint).Address.ToString(); newPlayer.Nation = Game.World.DefaultNation; IDatabase cache = World.DatastoreConnection.GetDatabase(); var myPerson = JsonConvert.SerializeObject(newPlayer); cache.Set(User.GetStorageKey(newPlayer.Name), myPerson); // Logger.ErrorFormat("Error saving new player!"); // Logger.ErrorFormat(e.ToString()); // client.LoginMessage("Unknown error. Contact [email protected]", 3); // } client.LoginMessage("\0", 0); } }
private void PacketHandler_0x39_NPCMainMenu(Object obj, ClientPacket packet) { var user = (User) obj; if (user.CheckSquelch(0x38, null)) { Logger.InfoFormat("{0}: squelched (NPC main menu)", user.Name); return; } // We just ignore the header, because, really, what exactly is a 16-bit encryption // key plus CRC really doing for you var header = packet.ReadDialogHeader(); var objectType = packet.ReadByte(); var objectId = packet.ReadUInt32(); var pursuitId = packet.ReadUInt16(); Logger.DebugFormat("main menu packet: ObjectType {0}, ID {1}, pursuitID {2}", objectType, objectId, pursuitId); // Sanity checks WorldObject wobj; if (Game.World.Objects.TryGetValue(objectId, out wobj)) { // Are we handling a global sequence? DialogSequence pursuit; VisibleObject clickTarget = wobj as VisibleObject; if (pursuitId < Constants.DIALOG_SEQUENCE_SHARED) { // Does the sequence exist in the global catalog? try { pursuit = Game.World.GlobalSequences[pursuitId]; } catch { Logger.ErrorFormat("{0}: pursuit ID {1} doesn't exist in the global catalog?", wobj.Name, pursuitId); return; } } else if (pursuitId >= Constants.DIALOG_SEQUENCE_HARDCODED) { if (!(wobj is Merchant)) { Logger.ErrorFormat("{0}: attempt to use hardcoded merchant menu item on non-merchant", wobj.Name, pursuitId); return; } var menuItem = (MerchantMenuItem) pursuitId; var merchant = (Merchant) wobj; MerchantMenuHandler handler; if (!merchantMenuHandlers.TryGetValue(menuItem, out handler)) { Logger.ErrorFormat("{0}: merchant menu item {1} doesn't exist?", wobj.Name, menuItem); return; } if (!merchant.Jobs.HasFlag(handler.RequiredJob)) { Logger.ErrorFormat("{0}: merchant does not have required job {1}", wobj.Name, handler.RequiredJob); return; } handler.Callback(user, merchant, packet); return; } else { // This is a local pursuit try { pursuit = clickTarget.Pursuits[pursuitId - Constants.DIALOG_SEQUENCE_SHARED]; } catch { Logger.ErrorFormat("{0}: local pursuit {1} doesn't exist?", wobj.Name, pursuitId); return; } } Logger.DebugFormat("{0}: showing initial dialog for Pursuit {1} ({2})", clickTarget.Name, pursuit.Id, pursuit.Name); user.DialogState.StartDialog(clickTarget, pursuit); pursuit.ShowTo(user, clickTarget); } else { Logger.WarnFormat("specified object ID {0} doesn't exist?", objectId); return; } }
private void PacketHandler_0x3A_DialogUse(Object obj, ClientPacket packet) { var user = (User) obj; if (user.CheckSquelch(0x38, null)) { Logger.InfoFormat("{0}: squelched (dialog use)", user.Name); return; } var header = packet.ReadDialogHeader(); var objectType = packet.ReadByte(); var objectID = packet.ReadUInt32(); var pursuitID = packet.ReadUInt16(); var pursuitIndex = packet.ReadUInt16(); Logger.DebugFormat("objectType {0}, objectID {1}, pursuitID {2}, pursuitIndex {3}", objectType, objectID, pursuitID, pursuitIndex); Logger.DebugFormat("active dialog via state object: pursuitID {0}, pursuitIndex {1}", user.DialogState.CurrentPursuitId, user.DialogState.CurrentPursuitIndex); if (pursuitID == user.DialogState.CurrentPursuitId && pursuitIndex == user.DialogState.CurrentPursuitIndex) { // If we get a packet back with the same index and ID, the dialog has been closed. Logger.DebugFormat("Dialog closed, resetting dialog state"); user.DialogState.EndDialog(); return; } if ((pursuitIndex > user.DialogState.CurrentPursuitIndex + 1) || (pursuitIndex < user.DialogState.CurrentPursuitIndex - 1)) { Logger.ErrorFormat("Dialog index is outside of acceptable limits (next/prev)"); return; } WorldObject wobj; if (user.World.Objects.TryGetValue(objectID, out wobj)) { VisibleObject clickTarget = wobj as VisibleObject; // Was the previous button clicked? Handle that first if (pursuitIndex == user.DialogState.CurrentPursuitIndex - 1) { Logger.DebugFormat("Handling prev: client passed index {0}, current index is {1}", pursuitIndex, user.DialogState.CurrentPursuitIndex); if (user.DialogState.SetDialogIndex(clickTarget, pursuitID, pursuitIndex)) { user.DialogState.ActiveDialog.ShowTo(user, clickTarget); return; } } // Is the active dialog an input or options dialog? if (user.DialogState.ActiveDialog is OptionsDialog) { var paramsLength = packet.ReadByte(); var option = packet.ReadByte(); var dialog = user.DialogState.ActiveDialog as OptionsDialog; dialog.HandleResponse(user, option, clickTarget); } if (user.DialogState.ActiveDialog is TextDialog) { var paramsLength = packet.ReadByte(); var response = packet.ReadString8(); var dialog = user.DialogState.ActiveDialog as TextDialog; dialog.HandleResponse(user, response, clickTarget); } // Did the handling of a response result in our active dialog sequence changing? If so, exit. if (user.DialogState.CurrentPursuitId != pursuitID) { Logger.DebugFormat("Dialog has changed, exiting"); return; } if (user.DialogState.SetDialogIndex(clickTarget, pursuitID, pursuitIndex)) { Logger.DebugFormat("Pursuit index is now {0}", pursuitIndex); user.DialogState.ActiveDialog.ShowTo(user, clickTarget); return; } else { Logger.DebugFormat("Sending close packet"); var p = new ServerPacket(0x30); p.WriteByte(0x0A); p.WriteByte(0x00); user.Enqueue(p); user.DialogState.EndDialog(); } } }
private void PacketHandler_0x43_PointClick(Object obj, ClientPacket packet) { var user = (User) obj; var clickType = packet.ReadByte(); Rectangle commonViewport = user.GetViewport(); // User has clicked an X,Y point if (clickType == 3) { var x = (byte) packet.ReadUInt16(); var y = (byte) packet.ReadUInt16(); var coords = new Tuple<byte, byte>(x, y); Logger.DebugFormat("coordinates were {0}, {1}", x, y); if (user.Map.Doors.ContainsKey(coords)) { if (user.Map.Doors[coords].Closed) user.SendMessage("It's open.", 0x1); else user.SendMessage("It's closed.", 0x1); user.Map.ToggleDoors(x, y); } else if (user.Map.Signposts.ContainsKey(coords)) { user.Map.Signposts[coords].OnClick(user); } else { Logger.DebugFormat("User clicked {0}@{1},{2} but no door/signpost is present", user.Map.Name, x, y); } } // User has clicked on another entity else if (clickType == 1) { var entityId = packet.ReadUInt32(); Logger.DebugFormat("User {0} clicked ID {1}: ", user.Name, entityId); WorldObject clickTarget = new WorldObject(); if (user.World.Objects.TryGetValue(entityId, out clickTarget)) { if (clickTarget is User || clickTarget is Merchant) { Type type = clickTarget.GetType(); MethodInfo methodInfo = type.GetMethod("OnClick"); methodInfo.Invoke(clickTarget, new[] {user}); } } } else { Logger.DebugFormat("Unsupported clickType {0}", clickType); Logger.DebugFormat("Packet follows:"); packet.DumpPacket(); } }
private void PacketHandler_0x10_ClientJoin(Client client, ClientPacket packet) { var seed = packet.ReadByte(); var keyLength = packet.ReadByte(); var key = packet.Read(keyLength); var name = packet.ReadString8(); var id = packet.ReadUInt32(); var redirect = ExpectedConnections[id]; if (redirect.Matches(name, key, seed)) { ((IDictionary)ExpectedConnections).Remove(id); client.EncryptionKey = key; client.EncryptionSeed = seed; if (redirect.Source is Lobby) { var x60 = new ServerPacket(0x60); x60.WriteByte(0x00); x60.WriteUInt32(Game.NotificationCrc); client.Enqueue(x60); } } }
private void PacketHandler_0x04_CreateB(Client client, ClientPacket packet) { if (string.IsNullOrEmpty(client.NewCharacterName) || string.IsNullOrEmpty(client.NewCharacterPassword)) { return; } var hairStyle = packet.ReadByte(); var sex = packet.ReadByte(); var hairColor = packet.ReadByte(); if (hairStyle < 1) { hairStyle = 1; } if (hairStyle > 17) { hairStyle = 17; } if (hairColor > 13) { hairColor = 13; } if (sex < 1) { sex = 1; } if (sex > 2) { sex = 2; } // Try to get our map // TODO: replace with XML config for start map, x, y Map map; if (!Game.World.WorldData.TryGetValue(136, out map)) { map = Game.World.WorldData.GetDictionary <Map>().First().Value; } if (!Game.World.PlayerExists(client.NewCharacterName)) { var newPlayer = new User(); newPlayer.Name = client.NewCharacterName; newPlayer.Sex = (Sex)sex; newPlayer.Location.Direction = Direction.South; newPlayer.Location.Map = map; newPlayer.Location.X = 10; newPlayer.Location.Y = 10; newPlayer.HairColor = hairColor; newPlayer.HairStyle = hairStyle; newPlayer.Class = Class.Peasant; newPlayer.Gold = 0; newPlayer.Login.CreatedTime = DateTime.Now; newPlayer.Password.Hash = client.NewCharacterPassword; newPlayer.Password.LastChanged = DateTime.Now; newPlayer.Password.LastChangedFrom = ((IPEndPoint)client.Socket.RemoteEndPoint).Address.ToString(); newPlayer.Nation = Game.World.DefaultNation; IDatabase cache = World.DatastoreConnection.GetDatabase(); var myPerson = JsonConvert.SerializeObject(newPlayer); cache.Set(User.GetStorageKey(newPlayer.Name), myPerson); // Logger.ErrorFormat("Error saving new player!"); // Logger.ErrorFormat(e.ToString()); // client.LoginMessage("Unknown error. Contact [email protected]", 3); // } client.LoginMessage("\0", 0); } }