public void SendPacket(SendPacketBase packet) { if (!_socket.Connected) { _conStatus = ConnStatus.Closed; return; } MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); packet.Write(_sequence++, bw); byte[] data = ms.ToArray(); LogInterface.Log(string.Format("Sent Packet to client ({0}) {1}: {2}", AccountID, packet.ToString(), data.Length), LogInterface.LogMessageType.Debug); LogInterface.Log(Utils.PrintBinaryData(data), LogInterface.LogMessageType.Debug); _scSec.EncryptInPlace(data); ms = new MemoryStream(); bw = new BinaryWriter(ms); bw.Write((ushort)data.Length); bw.Write(data); _socket.Send(ms.ToArray()); bw.Close(); }
void DumpPacketData(PacketHeader header, BinaryReader br) { byte[] data = br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position)); string output = Utils.PrintBinaryData(data); LogInterface.Log(output, LogInterface.LogMessageType.Debug, true); }
int ProcessPacket(byte[] data, int offset) { ushort verify = BitConverter.ToUInt16(data, 0); int dataLength = data[offset] | data[offset + 1] << 8; byte[] decrypted = _csSec.DecryptPacket(data, offset + 2, dataLength); // Grab the packet header MemoryStream mem = new MemoryStream(decrypted); BinaryReader br = new BinaryReader(mem); PacketHeader header = PacketHeader.Read(br); LogInterface.Log(string.Format("Recieved packet from client ({0}): 0x{1:x}", AccountID, header.Opcode), LogInterface.LogMessageType.Debug); // Dispatch the packet for further processing if (_packetHandlers.ContainsKey(header.Opcode)) { _packetHandlers[header.Opcode](header, br); } else { LogInterface.Log(string.Format("Unhandled packet 0x{0:x} - Length: {1}", header.Opcode, header.PacketLength), LogInterface.LogMessageType.Error, true); DumpPacketData(header, br); } return(dataLength + 2); }
void GiveItem_Handler(Task t) { GiveItemArgs args = (GiveItemArgs)t.Args; CharacterInfo ci = t.Client.Character; // Instantiate the item Item item = _server.InstantiateItem(args.ItemTemplateID); // Log it string log = string.Format("Giving item template({0}) to Character ID: {1}. Reason: {2}, Context: {3}", args.ItemTemplateID, ci.ID, args.Reason, args.Context); LogInterface.Log(log, LogInterface.LogMessageType.Game); // Do autostacking if (item.ItemType == Item.Type.Stackable) { // Find all existing stacks with this model id Item[] stacks = ci.FindItemsByModel(item.Model); if (stacks.Length > 0) { foreach (Item stack in stacks) { if (stack.StackSpace > 0) { // There is room in this stack, put items into this stack until full int amountToAdd = Math.Min(stack.StackSpace, item.Quantity); // Change this stacks quantity, save in the database, and send to the client stack.AddQuantity(amountToAdd); AddDBQuery(stack.UpdateDBString(), null, false); if (item.Quantity > amountToAdd) { t.Client.SendPacket(new GiveItemPacket(stack)); } // Remove the quantity from the new item item.AddQuantity(-amountToAdd); if (item.Quantity <= 0) { // All of the quantity has been distributed // Tell the client about the loot with the last stack t.Client.SendPacket(new ItemLootPacket(stack, args.Context)); return; } } } } } // Find a slot for it item.Slot = ci.FindGeneralSlot(); // Save it in the database string sql = item.WriteDBString(args.ItemTemplateID, ci.ID); t.Type = Task.TaskType.GiveItem_Finish; args.Item = item; AddDBQuery(sql, t); }
void LoadQuestRewards_Process_Handler(Task t) { if (t.Query.Rows.Count > 0) { Dictionary <ulong, QuestStep.Builder> steps = (Dictionary <ulong, QuestStep.Builder>)t.Args; // read and consolidate rewards foreach (object[] row in t.Query.Rows) { // 0: quest_id int(10) unsigned // 1: step tinyint(3) unsigned // 2: type tinyint(10) unsigned // 3: context int(10) unsigned uint quest = (uint)row[0]; byte step = (byte)row[1]; byte type = (byte)row[2]; uint context = (uint)row[3]; ulong key = ((ulong)step << 32) | quest; steps[key].AddReward(new QuestReward((QuestReward.RewardType)type, context)); } // now build all the quest steps Dictionary <uint, Quest.Builder> questBuilders = new Dictionary <uint, Quest.Builder>(); foreach (QuestStep.Builder qsb in steps.Values) { QuestStep step = qsb.Build(); if (!questBuilders.ContainsKey(step.QuestID)) { questBuilders[step.QuestID] = new Quest.Builder(step.QuestID); } questBuilders[step.QuestID].AddStep(step); } // now build all the quests Dictionary <uint, Quest> quests = new Dictionary <uint, Quest>(); foreach (KeyValuePair <uint, Quest.Builder> kvp in questBuilders) { Quest q = kvp.Value.Build(); quests[kvp.Key] = q; } // Give it to the server _server.QuestsLoaded(quests); // Load the quest info AddDBQuery("SELECT * FROM quest_requirements;", new Task(Task.TaskType.LoadQuestRequirements_Process)); } else { LogInterface.Log("Database does not contain any quest rewards. No quests will be available", LogInterface.LogMessageType.Game, true); } }
public int GetExpectedConnection(string authKey) { if (!_expectedConnections.ContainsKey(authKey)) { return(-1); } int account = _expectedConnections[authKey]; _expectedConnections.Remove(authKey); LogInterface.Log(string.Format("Got connection for account {0} with key {1}", account, authKey), LogInterface.LogMessageType.Security, false); return(account); }
public void Database_OnQueryComplete(object sender, EventArgs e) { DBQuery q = (DBQuery)sender; _pqLock.WaitOne(); LogInterface.Log("Finishing Query with key: " + q.Key, LogInterface.LogMessageType.Debug); Task task = _pendingQueries[q.Key]; _pendingQueries.Remove(q.Key); _pqLock.ReleaseMutex(); // reschedule the task to deal with the new data\ if (task.Type >= 0) { AddTask(task); } }
void GiveGoldExpFame_Handler(Task t) { GiveGoldExpFameArgs args = (GiveGoldExpFameArgs)t.Args; CharacterInfo ci = t.Client.Character; ci.GainGold((int)args.Gold); ci.GainExp(t.Client, (int)args.Exp); ci.GainFame(args.Fame); string sql = string.Format("UPDATE characters_hv SET gold={0},exp={1},fame={2} WHERE character_id={3};", ci.Gold, ci.Exp, ci.Fame, ci.ID); AddDBQuery(sql, null, false); string log = string.Format("Giving {0} gold, {1} exp, and {2} fame to Character ID: {3}. Reason: {4}, Context: {5}", args.Gold, args.Exp, args.Fame, ci.ID, args.Reason, args.Context); LogInterface.Log(log, LogInterface.LogMessageType.Game); // TODO: Figure out how to send this to the client }
void GMCommand_Process_Handler(Task t) { GMCommandPacket cmd = (GMCommandPacket)t.Args; string cmdString = string.Format("GM Command - {0} ({1}, {2}, {3}, {4}); Character: {5}", cmd.Command, cmd.Param, cmd.X, cmd.Y, cmd.Param2, cmd.Character); LogInterface.Log(cmdString); switch (cmd.Command) { case 0xfa3: AddTask(new Task(Task.TaskType.GiveItem, t.Client, new GiveItemArgs((uint)cmd.Param, GiveItemArgs.TheReason.GMCommand, 0))); break; default: //LogInterface.Log("Unhandled GM Command: 0x" + cmd.Command.ToString("x")); break; } }
void LoadQuestSteps_Process_Handler(Task t) { if (t.Query.Rows.Count > 0) { Dictionary <ulong, QuestStep.Builder> steps = new Dictionary <ulong, QuestStep.Builder>(); foreach (object[] row in t.Query.Rows) { // 0: quest_id int(10) unsigned // 1: step tinyint(3) unsigned // 2: type tinyint(3) unsigned // 3: count int(10) unsigned // 4: target_id int(10) unsigned // 5: owner_id int(10) unsigned uint quest = (uint)row[0]; byte step = (byte)row[1]; byte type = (byte)row[2]; uint count = row[3] == null ? 0 : (uint)row[3]; uint target = row[4] == null ? (uint)0 : (uint)row[4]; uint owner = (uint)row[5]; ulong key = ((ulong)step << 32) | quest; steps[key] = new QuestStep.Builder(quest, step, owner, (QuestStep.CompletionType)type, count, target); } // Put all the lines into the steps QuestLine[] lines = (QuestLine[])t.Args; foreach (QuestLine line in lines) { ulong key = ((ulong)line.StepNumber << 32) | line.QuestID; steps[key].AddLine(line); } // Now go gather all the rewards t.Args = steps; t.Type = Task.TaskType.LoadQuestRewards_Process; AddDBQuery("SELECT * FROM quest_rewards;", t); } else { LogInterface.Log("Database does not contain any quest steps. No quests will be available", LogInterface.LogMessageType.Game, true); } }
public DBQuery AddDBQuery(string sql, Task task, bool read = true) { if (task == null) { task = new Task(-1); } long key = UniqueKey(); DBQuery q = new DBQuery(sql, read, key); task.Query = q; _pqLock.WaitOne(); LogInterface.Log("Adding Query with key: " + key, LogInterface.LogMessageType.Debug, true); _pendingQueries[key] = task; _pqLock.ReleaseMutex(); _db.AddQuery(q); return(q); }
void LoadQuestLines_Process_Handler(Task t) { if (t.Query.Rows.Count > 0) { // Get the lines from the database List <QuestLine> lines = new List <QuestLine>(); foreach (object[] row in t.Query.Rows) { QuestLine line = QuestLine.ReadFromDB(row); lines.Add(line); } t.Type = Task.TaskType.LoadQuestSteps_Process; t.Args = lines.ToArray(); AddDBQuery("SELECT * FROM quest_steps;", t); } else { LogInterface.Log("Database does not contain any quest lines. No quests will be available", LogInterface.LogMessageType.Game, true); } }
void LoadQuestInfo_Process_Handler(Task t) { if (t.Query.Rows.Count > 0) { foreach (object[] row in t.Query.Rows) { // 0: quest_id int(10) unsigned // 1: giver_id int(10) unsigned // 2: giver_map_id smallint(5) unsigned uint questID = (uint)row[0]; uint giver = (uint)row[1]; ushort map = (ushort)row[2]; _server.SetQuestGiver(questID, giver, map); } } else { LogInterface.Log("Database does not contain any quest info. No quests will be available", LogInterface.LogMessageType.Game, true); } _server.AllowConnections(); }
public string ExpectConnection(int accountId) { Int64 code = accountId * DateTime.Now.Ticks; string authKey = ""; do { authKey = ""; for (int i = 0; i < 8; i++) { byte p = (byte)((code >> (i * 8)) & 0xFF); if (p != 0) { authKey += p.ToString("X2"); } } } while(_expectedConnections.ContainsKey(authKey)); _expectedConnections[authKey] = accountId; LogInterface.Log(string.Format("Expecting client for account {0} with key {1}", accountId, authKey), LogInterface.LogMessageType.Security, false); return(authKey); }
public static void Log(string message, LogMessageType type = LogMessageType.Normal, bool logToConsole = false) { _log.Log(type, logToConsole, message); }
public void QuestsLoaded(Dictionary <uint, Quest> quests) { _quests = quests; LogInterface.Log(string.Format("Loaded {0} quests", quests.Count), LogInterface.LogMessageType.Game, true); }