mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-24 13:47:46 +00:00
Got aetheryte map and completed quest work values... working.
This commit is contained in:
parent
a2c4d077e9
commit
306f4ef346
11 changed files with 546 additions and 382 deletions
|
@ -9,7 +9,7 @@ namespace Meteor.Common
|
||||||
{
|
{
|
||||||
public class Bitstream
|
public class Bitstream
|
||||||
{
|
{
|
||||||
private readonly byte[] Data;
|
private byte[] Data;
|
||||||
|
|
||||||
public Bitstream(uint numBits, bool setAllTrue = false)
|
public Bitstream(uint numBits, bool setAllTrue = false)
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,12 @@ namespace Meteor.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetTo(bool[] result)
|
||||||
|
{
|
||||||
|
Debug.Assert(Data.Length == result.Length / 8);
|
||||||
|
Data = Utils.ConvertBoolArrayToBinaryStream(result);
|
||||||
|
}
|
||||||
|
|
||||||
public bool Get(uint at)
|
public bool Get(uint at)
|
||||||
{
|
{
|
||||||
return Get((int)at);
|
return Get((int)at);
|
||||||
|
@ -60,6 +66,7 @@ namespace Meteor.Common
|
||||||
{
|
{
|
||||||
int bytePos = at / 8;
|
int bytePos = at / 8;
|
||||||
int bitPos = at % 8;
|
int bitPos = at % 8;
|
||||||
|
|
||||||
return (Data[bytePos] & (1 << bitPos)) != 0;
|
return (Data[bytePos] & (1 << bitPos)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,5 +153,46 @@ namespace Meteor.Common
|
||||||
return Data;
|
return Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] GetSlice(ushort from, ushort to)
|
||||||
|
{
|
||||||
|
int remainder = ((to - from) % 8 != 0) ? 1 : 0;
|
||||||
|
byte[] toReturn = new byte[((to - from) / 8) + remainder + 1];
|
||||||
|
toReturn[toReturn.Length - 1] = 0x3;
|
||||||
|
|
||||||
|
|
||||||
|
byte curByte = 0;
|
||||||
|
|
||||||
|
int destByteIndx = 0;
|
||||||
|
int destShiftIndx = 0;
|
||||||
|
int srcByteIndx = from / 8;
|
||||||
|
int srcShiftIndx = from % 8;
|
||||||
|
|
||||||
|
for (int i = from; i <= to; i++)
|
||||||
|
{
|
||||||
|
// Skip Zeros
|
||||||
|
if (Data[srcByteIndx] == 0)
|
||||||
|
{
|
||||||
|
srcByteIndx++;
|
||||||
|
srcShiftIndx = 0;
|
||||||
|
destByteIndx++;
|
||||||
|
i += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool val = (Data[srcByteIndx] & (1 << srcShiftIndx)) != 0;
|
||||||
|
|
||||||
|
curByte |= (byte)((val ? 1 : 0) << destShiftIndx++);
|
||||||
|
if (destShiftIndx == 8)
|
||||||
|
{
|
||||||
|
toReturn[destByteIndx++] = curByte;
|
||||||
|
destShiftIndx = 0;
|
||||||
|
curByte = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destByteIndx == toReturn.Length - 2)
|
||||||
|
toReturn[destByteIndx] = curByte;
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,6 +255,26 @@ namespace Meteor.Common
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool[] ConvertBinaryStreamToBoolArray(byte[] bytes)
|
||||||
|
{
|
||||||
|
bool[] data = new bool[bytes.Length * 8];
|
||||||
|
|
||||||
|
int boolCounter = 0;
|
||||||
|
for (int i = 0; i < bytes.Length; i ++)
|
||||||
|
{
|
||||||
|
if (bytes[i] == 0)
|
||||||
|
{
|
||||||
|
boolCounter += 8;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int bitCount = 0; bitCount < 8; bitCount++)
|
||||||
|
data[boolCounter++] = (bytes[i] >> bitCount & 1) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
public static string ToStringBase63(int number)
|
public static string ToStringBase63(int number)
|
||||||
{
|
{
|
||||||
var lookup = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
var lookup = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
|
@ -74,7 +74,7 @@ function onTalk(player, quest, npc, eventName)
|
||||||
-- Offer the quest
|
-- Offer the quest
|
||||||
if (npcClassId == KINNISON and not player:HasQuest(quest)) then
|
if (npcClassId == KINNISON and not player:HasQuest(quest)) then
|
||||||
local questAccepted = callClientFunction(player, "delegateEvent", player, quest, "processEventOffersStart");
|
local questAccepted = callClientFunction(player, "delegateEvent", player, quest, "processEventOffersStart");
|
||||||
if (questAccepted) then
|
if (questAccepted == 1) then
|
||||||
player:AcceptQuest(quest);
|
player:AcceptQuest(quest);
|
||||||
end
|
end
|
||||||
player:EndEvent();
|
player:EndEvent();
|
||||||
|
@ -146,7 +146,7 @@ function onTalk(player, quest, npc, eventName)
|
||||||
if (npcClassId == KINNISON) then
|
if (npcClassId == KINNISON) then
|
||||||
callClientFunction(player, "delegateEvent", player, quest, "processEventClear");
|
callClientFunction(player, "delegateEvent", player, quest, "processEventClear");
|
||||||
callClientFunction(player, "delegateEvent", player, quest, "sqrwa", 200, 1, 1, 9);
|
callClientFunction(player, "delegateEvent", player, quest, "sqrwa", 200, 1, 1, 9);
|
||||||
player:CompleteQuest(quest:GetQuestId());
|
player:CompleteQuest(quest);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
quest:UpdateENPCs();
|
quest:UpdateENPCs();
|
||||||
|
|
|
@ -47,6 +47,7 @@ using Meteor.Map.packets.send.actor.battle;
|
||||||
using Meteor.Map.packets.receive.events;
|
using Meteor.Map.packets.receive.events;
|
||||||
using static Meteor.Map.LuaUtils;
|
using static Meteor.Map.LuaUtils;
|
||||||
using Meteor.Map.packets.send.actor.events;
|
using Meteor.Map.packets.send.actor.events;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Meteor.Map.Actors
|
namespace Meteor.Map.Actors
|
||||||
{
|
{
|
||||||
|
@ -243,8 +244,7 @@ namespace Meteor.Map.Actors
|
||||||
charaWork.command[15] = 0xA0F00000 | 22015;
|
charaWork.command[15] = 0xA0F00000 | 22015;
|
||||||
|
|
||||||
charaWork.commandAcquired[27150 - 26000] = true;
|
charaWork.commandAcquired[27150 - 26000] = true;
|
||||||
|
|
||||||
playerWork.questScenarioComplete[110001 - 110001] = true;
|
|
||||||
playerWork.questGuildleveComplete[120050 - 120001] = true;
|
playerWork.questGuildleveComplete[120050 - 120001] = true;
|
||||||
|
|
||||||
for (int i = 0; i < charaWork.additionalCommandAcquired.Length; i++ )
|
for (int i = 0; i < charaWork.additionalCommandAcquired.Length; i++ )
|
||||||
|
@ -278,7 +278,7 @@ namespace Meteor.Map.Actors
|
||||||
CalculateBaseStats();
|
CalculateBaseStats();
|
||||||
|
|
||||||
questStateManager = new QuestStateManager(this);
|
questStateManager = new QuestStateManager(this);
|
||||||
questStateManager.Init(questScenario);
|
questStateManager.Init(questScenario, playerWork.questScenarioComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SubPacket> Create0x132Packets()
|
public List<SubPacket> Create0x132Packets()
|
||||||
|
@ -1157,6 +1157,44 @@ namespace Meteor.Map.Actors
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SendAchievedAetheryte(ushort from, ushort to)
|
||||||
|
{
|
||||||
|
Bitstream fakeAetheryte = new Bitstream(512, true);
|
||||||
|
|
||||||
|
SetActorPropetyPacket completedQuestWorkUpdate = new SetActorPropetyPacket(from, to, "work/achieveAetheryte");
|
||||||
|
completedQuestWorkUpdate.AddBitfield(Utils.MurmurHash2("work.event_achieve_aetheryte", 0), fakeAetheryte.GetSlice(from, to));
|
||||||
|
completedQuestWorkUpdate.AddTarget();
|
||||||
|
QueuePacket(completedQuestWorkUpdate.BuildPacket(Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendCompletedQuests(ushort from, ushort to)
|
||||||
|
{
|
||||||
|
Bitstream completed = questStateManager.GetCompletedBitstream();
|
||||||
|
completed.SetAll(true);
|
||||||
|
byte[] data = completed.GetSlice(from, to);
|
||||||
|
|
||||||
|
SetActorPropetyPacket completedQuestWorkUpdate = new SetActorPropetyPacket(from, to, "playerWork/journal");
|
||||||
|
completedQuestWorkUpdate.AddBitfield(Utils.MurmurHash2("playerWork.questScenarioComplete", 0), data);
|
||||||
|
completedQuestWorkUpdate.AddTarget();
|
||||||
|
QueuePacket(completedQuestWorkUpdate.BuildPacket(Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnWorkSyncRequest(string propertyName, ushort from = 0, ushort to = 0)
|
||||||
|
{
|
||||||
|
switch (propertyName)
|
||||||
|
{
|
||||||
|
case "charaWork/exp":
|
||||||
|
SendCharaExpInfo();
|
||||||
|
break;
|
||||||
|
case "work/achieveAetheryte":
|
||||||
|
SendAchievedAetheryte(from, to);
|
||||||
|
break;
|
||||||
|
case "playerWork/questCompleteS":
|
||||||
|
SendCompletedQuests(from, to);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int GetHighestLevel()
|
public int GetHighestLevel()
|
||||||
{
|
{
|
||||||
int max = 0;
|
int max = 0;
|
||||||
|
@ -1436,7 +1474,6 @@ namespace Meteor.Map.Actors
|
||||||
|
|
||||||
playerWork.questScenario[freeSlot] = instance.Id;
|
playerWork.questScenario[freeSlot] = instance.Id;
|
||||||
questScenario[freeSlot] = instance;
|
questScenario[freeSlot] = instance;
|
||||||
Database.SaveQuest(this, questScenario[freeSlot], freeSlot);
|
|
||||||
SendQuestClientUpdate(freeSlot);
|
SendQuestClientUpdate(freeSlot);
|
||||||
|
|
||||||
if (!isSilent)
|
if (!isSilent)
|
||||||
|
@ -1446,6 +1483,8 @@ namespace Meteor.Map.Actors
|
||||||
|
|
||||||
instance.OnAccept();
|
instance.OnAccept();
|
||||||
|
|
||||||
|
Database.SaveQuest(this, questScenario[freeSlot], freeSlot);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1458,8 +1497,11 @@ namespace Meteor.Map.Actors
|
||||||
{
|
{
|
||||||
questScenario[i] = newQuestInstance;
|
questScenario[i] = newQuestInstance;
|
||||||
playerWork.questScenario[i] = questScenario[i].Id;
|
playerWork.questScenario[i] = questScenario[i].Id;
|
||||||
Database.SaveQuest(this, questScenario[i], i);
|
|
||||||
SendQuestClientUpdate(i);
|
SendQuestClientUpdate(i);
|
||||||
|
oldQuestInstance.OnComplete();
|
||||||
|
questStateManager.UpdateQuestCompleted(oldQuestInstance);
|
||||||
|
newQuestInstance.OnAccept();
|
||||||
|
Database.SaveQuest(this, questScenario[i], i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1472,14 +1514,14 @@ namespace Meteor.Map.Actors
|
||||||
{
|
{
|
||||||
// Remove the quest from the DB and update client work values
|
// Remove the quest from the DB and update client work values
|
||||||
playerWork.questScenarioComplete[completed.GetQuestId() - 110001] = true;
|
playerWork.questScenarioComplete[completed.GetQuestId() - 110001] = true;
|
||||||
Database.CompleteQuest(playerSession.GetActor(), completed.Id);
|
|
||||||
Database.RemoveQuest(this, completed.Id);
|
|
||||||
questScenario[slot] = null;
|
questScenario[slot] = null;
|
||||||
playerWork.questScenario[slot] = 0;
|
playerWork.questScenario[slot] = 0;
|
||||||
SendQuestClientUpdate(slot);
|
SendQuestClientUpdate(slot);
|
||||||
|
|
||||||
// Reset active quest and quest state
|
// Reset active quest and quest state
|
||||||
completed.OnComplete();
|
completed.OnComplete();
|
||||||
|
Database.SaveCompletedQuests(playerSession.GetActor());
|
||||||
|
Database.RemoveQuest(this, completed.Id);
|
||||||
questStateManager.UpdateQuestCompleted(completed);
|
questStateManager.UpdateQuestCompleted(completed);
|
||||||
|
|
||||||
// Msg Player
|
// Msg Player
|
||||||
|
@ -1512,13 +1554,13 @@ namespace Meteor.Map.Actors
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the quest from the DB and update client work values
|
// Remove the quest from the DB and update client work values
|
||||||
Database.RemoveQuest(this, abandoned.Id);
|
|
||||||
questScenario[slot] = null;
|
questScenario[slot] = null;
|
||||||
playerWork.questScenario[slot] = 0;
|
playerWork.questScenario[slot] = 0;
|
||||||
SendQuestClientUpdate(slot);
|
SendQuestClientUpdate(slot);
|
||||||
|
|
||||||
// Reset active quest and quest state
|
// Reset active quest and quest state
|
||||||
abandoned.OnAbandon();
|
abandoned.OnAbandon();
|
||||||
|
Database.RemoveQuest(this, abandoned.Id);
|
||||||
questStateManager.UpdateQuestAbandoned();
|
questStateManager.UpdateQuestAbandoned();
|
||||||
|
|
||||||
// Msg Player
|
// Msg Player
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace Meteor.Map.Actors.QuestNS
|
||||||
private const int SCENARIO_MAX = 2048;
|
private const int SCENARIO_MAX = 2048;
|
||||||
|
|
||||||
private readonly Player player;
|
private readonly Player player;
|
||||||
|
private readonly Bitstream CompletedQuestsBitfield = new Bitstream(SCENARIO_MAX);
|
||||||
private readonly Bitstream AvailableQuestsBitfield = new Bitstream(SCENARIO_MAX);
|
private readonly Bitstream AvailableQuestsBitfield = new Bitstream(SCENARIO_MAX);
|
||||||
private readonly Bitstream MinLevelBitfield = new Bitstream(SCENARIO_MAX);
|
private readonly Bitstream MinLevelBitfield = new Bitstream(SCENARIO_MAX);
|
||||||
private readonly Bitstream PrereqBitfield = new Bitstream(SCENARIO_MAX, true);
|
private readonly Bitstream PrereqBitfield = new Bitstream(SCENARIO_MAX, true);
|
||||||
|
@ -28,12 +29,12 @@ namespace Meteor.Map.Actors.QuestNS
|
||||||
this.player = player;
|
this.player = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init(Quest[] questScenario)
|
public void Init(Quest[] journalQuests, bool[] completedQuests)
|
||||||
{
|
{
|
||||||
// Preload any quests that the player loaded
|
// Preload any quests that the player loaded
|
||||||
if (questScenario != null)
|
if (journalQuests != null)
|
||||||
{
|
{
|
||||||
foreach (var quest in questScenario)
|
foreach (var quest in journalQuests)
|
||||||
{
|
{
|
||||||
if (quest != null)
|
if (quest != null)
|
||||||
{
|
{
|
||||||
|
@ -49,10 +50,10 @@ namespace Meteor.Map.Actors.QuestNS
|
||||||
MinLevelBitfield.Set(questData.Id - SCENARIO_START);
|
MinLevelBitfield.Set(questData.Id - SCENARIO_START);
|
||||||
|
|
||||||
// Init Prereq
|
// Init Prereq
|
||||||
Bitstream completed = new Bitstream(player.playerWork.questScenarioComplete);
|
CompletedQuestsBitfield.SetTo(completedQuests);
|
||||||
foreach (var questData in Server.GetQuestGamedataAllPrerequisite())
|
foreach (var questData in Server.GetQuestGamedataAllPrerequisite())
|
||||||
{
|
{
|
||||||
if (completed.Get(((Quest)Server.GetStaticActors(0xA0F00000 | questData.PrerequisiteQuest)).GetQuestId() - SCENARIO_START))
|
if (CompletedQuestsBitfield.Get(((Quest)Server.GetStaticActors(0xA0F00000 | questData.PrerequisiteQuest)).GetQuestId() - SCENARIO_START))
|
||||||
PrereqBitfield.Set(questData.Id - SCENARIO_START);
|
PrereqBitfield.Set(questData.Id - SCENARIO_START);
|
||||||
else
|
else
|
||||||
PrereqBitfield.Clear(questData.Id - SCENARIO_START);
|
PrereqBitfield.Clear(questData.Id - SCENARIO_START);
|
||||||
|
@ -71,6 +72,7 @@ namespace Meteor.Map.Actors.QuestNS
|
||||||
|
|
||||||
public void UpdateQuestCompleted(Quest quest)
|
public void UpdateQuestCompleted(Quest quest)
|
||||||
{
|
{
|
||||||
|
CompletedQuestsBitfield.Set(quest.Id - SCENARIO_START);
|
||||||
QuestGameData[] updated = Server.GetQuestGamedataByPrerequisite(quest.GetQuestId());
|
QuestGameData[] updated = Server.GetQuestGamedataByPrerequisite(quest.GetQuestId());
|
||||||
foreach (var questData in updated)
|
foreach (var questData in updated)
|
||||||
PrereqBitfield.Set(questData.Id - SCENARIO_START);
|
PrereqBitfield.Set(questData.Id - SCENARIO_START);
|
||||||
|
@ -84,7 +86,8 @@ namespace Meteor.Map.Actors.QuestNS
|
||||||
|
|
||||||
private void ComputeAvailable()
|
private void ComputeAvailable()
|
||||||
{
|
{
|
||||||
Bitstream result = new Bitstream(player.playerWork.questScenarioComplete);
|
Bitstream result = new Bitstream(SCENARIO_MAX);
|
||||||
|
result.OR(CompletedQuestsBitfield);
|
||||||
result.NOT();
|
result.NOT();
|
||||||
result.AND(MinLevelBitfield);
|
result.AND(MinLevelBitfield);
|
||||||
result.AND(PrereqBitfield);
|
result.AND(PrereqBitfield);
|
||||||
|
@ -152,5 +155,10 @@ namespace Meteor.Map.Actors.QuestNS
|
||||||
{
|
{
|
||||||
return ActiveQuests.FindAll(quest => quest.IsQuestENPC(player, npc)).ToArray();
|
return ActiveQuests.FindAll(quest => quest.IsQuestENPC(player, npc)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Bitstream GetCompletedBitstream()
|
||||||
|
{
|
||||||
|
return CompletedQuestsBitfield;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -763,7 +763,7 @@ namespace Meteor.Map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CompleteQuest(Player player, uint questId)
|
public static void SaveCompletedQuests(Player player)
|
||||||
{
|
{
|
||||||
string query;
|
string query;
|
||||||
MySqlCommand cmd;
|
MySqlCommand cmd;
|
||||||
|
@ -776,15 +776,15 @@ namespace Meteor.Map
|
||||||
|
|
||||||
query = @"
|
query = @"
|
||||||
INSERT INTO characters_quest_completed
|
INSERT INTO characters_quest_completed
|
||||||
(characterId, questId)
|
(characterId, completedQuests)
|
||||||
VALUES
|
VALUES
|
||||||
(@charaId, @questId)
|
(@charaId, @completedQuests)
|
||||||
ON DUPLICATE KEY UPDATE characterId=characterId
|
ON DUPLICATE KEY UPDATE completedQuests=completedQuests
|
||||||
";
|
";
|
||||||
|
|
||||||
cmd = new MySqlCommand(query, conn);
|
cmd = new MySqlCommand(query, conn);
|
||||||
cmd.Parameters.AddWithValue("@charaId", player.Id);
|
cmd.Parameters.AddWithValue("@charaId", player.Id);
|
||||||
cmd.Parameters.AddWithValue("@questId", 0xFFFFF & questId);
|
cmd.Parameters.AddWithValue("@completedQuests", Utils.ConvertBoolArrayToBinaryStream(player.playerWork.questScenarioComplete));
|
||||||
|
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
@ -799,31 +799,6 @@ namespace Meteor.Map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsQuestCompleted(Player player, uint questId)
|
|
||||||
{
|
|
||||||
bool isCompleted = false;
|
|
||||||
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
conn.Open();
|
|
||||||
MySqlCommand cmd = new MySqlCommand("SELECT * FROM characters_quest_completed WHERE characterId = @charaId and questId = @questId", conn);
|
|
||||||
cmd.Parameters.AddWithValue("@charaId", player.Id);
|
|
||||||
cmd.Parameters.AddWithValue("@questId", questId);
|
|
||||||
isCompleted = cmd.ExecuteScalar() != null;
|
|
||||||
}
|
|
||||||
catch (MySqlException e)
|
|
||||||
{
|
|
||||||
Program.Log.Error(e.ToString());
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
conn.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isCompleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LoadPlayerCharacter(Player player)
|
public static void LoadPlayerCharacter(Player player)
|
||||||
{
|
{
|
||||||
string query;
|
string query;
|
||||||
|
@ -1267,6 +1242,25 @@ namespace Meteor.Map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Load Completed Quests bitstream
|
||||||
|
query = @"
|
||||||
|
SELECT
|
||||||
|
completedQuests
|
||||||
|
FROM characters_quest_completed WHERE characterId = @charaId";
|
||||||
|
|
||||||
|
cmd = new MySqlCommand(query, conn);
|
||||||
|
cmd.Parameters.AddWithValue("@charaId", player.Id);
|
||||||
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
// Replace the bool stream or use the default empty one.
|
||||||
|
if (reader.Read())
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[256];
|
||||||
|
reader.GetBytes(reader.GetOrdinal("completedQuests"), 0, bytes, 0, 256);
|
||||||
|
player.playerWork.questScenarioComplete = Utils.ConvertBinaryStreamToBoolArray(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Load Local Guildleves
|
//Load Local Guildleves
|
||||||
query = @"
|
query = @"
|
||||||
SELECT
|
SELECT
|
||||||
|
|
|
@ -227,7 +227,7 @@
|
||||||
<Compile Include="Packets\Receive\CountdownRequestPacket.cs" />
|
<Compile Include="Packets\Receive\CountdownRequestPacket.cs" />
|
||||||
<Compile Include="Packets\Receive\LangaugeCodePacket.cs" />
|
<Compile Include="Packets\Receive\LangaugeCodePacket.cs" />
|
||||||
<Compile Include="Packets\Receive\UpdateItemPackagePacket.cs" />
|
<Compile Include="Packets\Receive\UpdateItemPackagePacket.cs" />
|
||||||
<Compile Include="Packets\Receive\ParameterDataRequestPacket.cs" />
|
<Compile Include="Packets\Receive\WorkSyncRequestPacket.cs" />
|
||||||
<Compile Include="Packets\Receive\Recruitment\RecruitmentDetailsRequestPacket.cs" />
|
<Compile Include="Packets\Receive\Recruitment\RecruitmentDetailsRequestPacket.cs" />
|
||||||
<Compile Include="Packets\Receive\Recruitment\RecruitmentSearchRequestPacket.cs" />
|
<Compile Include="Packets\Receive\Recruitment\RecruitmentSearchRequestPacket.cs" />
|
||||||
<Compile Include="Packets\Receive\Recruitment\StartRecruitingRequestPacket.cs" />
|
<Compile Include="Packets\Receive\Recruitment\StartRecruitingRequestPacket.cs" />
|
||||||
|
|
|
@ -39,6 +39,7 @@ using Meteor.Map.Actors;
|
||||||
using Meteor.Map.packets.WorldPackets.Send;
|
using Meteor.Map.packets.WorldPackets.Send;
|
||||||
using Meteor.Map.packets.WorldPackets.Receive;
|
using Meteor.Map.packets.WorldPackets.Receive;
|
||||||
using Meteor.Map.actors.director;
|
using Meteor.Map.actors.director;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Meteor.Map
|
namespace Meteor.Map
|
||||||
{
|
{
|
||||||
|
@ -49,345 +50,344 @@ namespace Meteor.Map
|
||||||
public PacketProcessor(Server server)
|
public PacketProcessor(Server server)
|
||||||
{
|
{
|
||||||
mServer = server;
|
mServer = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessPacket(ZoneConnection client, SubPacket subpacket)
|
public void ProcessPacket(ZoneConnection client, SubPacket subpacket)
|
||||||
{
|
{
|
||||||
Session session = mServer.GetSession(subpacket.header.sourceId);
|
Session session = mServer.GetSession(subpacket.header.sourceId);
|
||||||
|
|
||||||
if (session == null && subpacket.gameMessage.opcode != 0x1000)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Normal Game Opcode
|
|
||||||
switch (subpacket.gameMessage.opcode)
|
|
||||||
{
|
|
||||||
//World Server - Error
|
|
||||||
case 0x100A:
|
|
||||||
ErrorPacket worldError = new ErrorPacket(subpacket.data);
|
|
||||||
switch (worldError.errorCode)
|
|
||||||
{
|
|
||||||
case 0x01:
|
|
||||||
session.GetActor().SendGameMessage(Server.GetWorldManager().GetActor(), 60005, 0x20);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
//World Server - Session Begin
|
|
||||||
case 0x1000:
|
|
||||||
subpacket.DebugPrintSubPacket();
|
|
||||||
|
|
||||||
SessionBeginPacket beginSessionPacket = new SessionBeginPacket(subpacket.data);
|
|
||||||
|
|
||||||
session = mServer.AddSession(subpacket.header.sourceId);
|
|
||||||
|
|
||||||
if (!beginSessionPacket.isLogin)
|
|
||||||
Server.GetWorldManager().DoZoneIn(session.GetActor(), false, session.GetActor().destinationSpawnType);
|
|
||||||
|
|
||||||
Program.Log.Info("{0} has been added to the session list.", session.GetActor().DisplayName);
|
|
||||||
|
|
||||||
client.FlushQueuedSendPackets();
|
|
||||||
break;
|
|
||||||
//World Server - Session End
|
|
||||||
case 0x1001:
|
|
||||||
SessionEndPacket endSessionPacket = new SessionEndPacket(subpacket.data);
|
|
||||||
|
|
||||||
if (endSessionPacket.destinationZoneId == 0)
|
|
||||||
session.GetActor().CleanupAndSave();
|
|
||||||
else
|
|
||||||
session.GetActor().CleanupAndSave(endSessionPacket.destinationZoneId, endSessionPacket.destinationSpawnType, endSessionPacket.destinationX, endSessionPacket.destinationY, endSessionPacket.destinationZ, endSessionPacket.destinationRot);
|
|
||||||
|
|
||||||
Server.GetServer().RemoveSession(session.id);
|
|
||||||
Program.Log.Info("{0} has been removed from the session list.", session.GetActor().DisplayName);
|
|
||||||
|
|
||||||
session.QueuePacket(SessionEndConfirmPacket.BuildPacket(session, endSessionPacket.destinationZoneId));
|
|
||||||
client.FlushQueuedSendPackets();
|
|
||||||
break;
|
|
||||||
//World Server - Party Synch
|
|
||||||
case 0x1020:
|
|
||||||
PartySyncPacket partySyncPacket = new PartySyncPacket(subpacket.data);
|
|
||||||
Server.GetWorldManager().PartyMemberListRecieved(partySyncPacket);
|
|
||||||
break;
|
|
||||||
//World Server - Linkshell Creation Result
|
|
||||||
case 0x1025:
|
|
||||||
LinkshellResultPacket lsResult = new LinkshellResultPacket(subpacket.data);
|
|
||||||
LuaEngine.GetInstance().OnSignal("ls_result", lsResult.resultCode);
|
|
||||||
break;
|
|
||||||
//Ping
|
|
||||||
case 0x0001:
|
|
||||||
//subpacket.DebugPrintSubPacket();
|
|
||||||
PingPacket pingPacket = new PingPacket(subpacket.data);
|
|
||||||
session.QueuePacket(PongPacket.BuildPacket(session.id, pingPacket.time));
|
|
||||||
session.Ping();
|
|
||||||
break;
|
|
||||||
//Unknown
|
|
||||||
case 0x0002:
|
|
||||||
|
|
||||||
subpacket.DebugPrintSubPacket();
|
|
||||||
session.QueuePacket(_0x2Packet.BuildPacket(session.id));
|
|
||||||
client.FlushQueuedSendPackets();
|
|
||||||
|
|
||||||
break;
|
|
||||||
//Chat Received
|
|
||||||
case 0x0003:
|
|
||||||
ChatMessagePacket chatMessage = new ChatMessagePacket(subpacket.data);
|
|
||||||
//Program.Log.Info("Got type-{5} message: {0} @ {1}, {2}, {3}, Rot: {4}", chatMessage.message, chatMessage.posX, chatMessage.posY, chatMessage.posZ, chatMessage.posRot, chatMessage.logType);
|
|
||||||
|
|
||||||
if (chatMessage.message.StartsWith("!"))
|
|
||||||
{
|
|
||||||
if (Server.GetCommandProcessor().DoCommand(chatMessage.message, session))
|
|
||||||
return; ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SAY || chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SHOUT)
|
|
||||||
session.GetActor().BroadcastPacket(SendMessagePacket.BuildPacket(session.id, chatMessage.logType, session.GetActor().DisplayName, chatMessage.message), false);
|
|
||||||
|
|
||||||
break;
|
|
||||||
//Langauge Code (Client safe to send packets to now)
|
|
||||||
case 0x0006:
|
|
||||||
LangaugeCodePacket langCode = new LangaugeCodePacket(subpacket.data);
|
|
||||||
LuaEngine.GetInstance().CallLuaFunction(session.GetActor(), session.GetActor(), "onBeginLogin", true);
|
|
||||||
Server.GetWorldManager().DoZoneIn(session.GetActor(), true, 0x1);
|
|
||||||
LuaEngine.GetInstance().CallLuaFunction(session.GetActor(), session.GetActor(), "onLogin", true);
|
|
||||||
session.languageCode = langCode.languageCode;
|
|
||||||
break;
|
|
||||||
//Unknown - Happens a lot at login, then once every time player zones
|
|
||||||
case 0x0007:
|
|
||||||
//subpacket.DebugPrintSubPacket();
|
|
||||||
ZoneInCompletePacket zoneInCompletePacket = new ZoneInCompletePacket(subpacket.data);
|
|
||||||
break;
|
|
||||||
//Update Position
|
|
||||||
case 0x00CA:
|
|
||||||
//Update Position
|
|
||||||
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
|
|
||||||
session.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
|
|
||||||
session.GetActor().SendInstanceUpdate();
|
|
||||||
|
|
||||||
if (session.GetActor().IsInZoneChange())
|
|
||||||
session.GetActor().SetZoneChanging(false);
|
|
||||||
|
|
||||||
break;
|
|
||||||
//Set Target
|
|
||||||
case 0x00CD:
|
|
||||||
//subpacket.DebugPrintSubPacket();
|
|
||||||
|
|
||||||
SetTargetPacket setTarget = new SetTargetPacket(subpacket.data);
|
|
||||||
session.GetActor().currentTarget = setTarget.actorID;
|
|
||||||
session.GetActor().isAutoAttackEnabled = setTarget.attackTarget != 0xE0000000;
|
|
||||||
session.GetActor().BroadcastPacket(SetActorTargetAnimatedPacket.BuildPacket(session.id, setTarget.actorID), true);
|
|
||||||
break;
|
|
||||||
//Lock Target
|
|
||||||
case 0x00CC:
|
|
||||||
LockTargetPacket lockTarget = new LockTargetPacket(subpacket.data);
|
|
||||||
session.GetActor().currentLockedTarget = lockTarget.actorID;
|
|
||||||
break;
|
|
||||||
//Start Event
|
|
||||||
case 0x012D:
|
|
||||||
subpacket.DebugPrintSubPacket();
|
|
||||||
EventStartPacket eventStart = new EventStartPacket(subpacket.data);
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (eventStart.error != null)
|
|
||||||
{
|
|
||||||
player.errorMessage += eventStart.error;
|
|
||||||
|
|
||||||
if (eventStart.errorIndex == eventStart.errorNum - 1)
|
|
||||||
Program.Log.Error("\n"+player.errorMessage);
|
|
||||||
|
|
||||||
|
if (session == null && subpacket.gameMessage.opcode != 0x1000)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Normal Game Opcode
|
||||||
|
switch (subpacket.gameMessage.opcode)
|
||||||
|
{
|
||||||
|
//World Server - Error
|
||||||
|
case 0x100A:
|
||||||
|
ErrorPacket worldError = new ErrorPacket(subpacket.data);
|
||||||
|
switch (worldError.errorCode)
|
||||||
|
{
|
||||||
|
case 0x01:
|
||||||
|
session.GetActor().SendGameMessage(Server.GetWorldManager().GetActor(), 60005, 0x20);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/
|
break;
|
||||||
|
//World Server - Session Begin
|
||||||
|
case 0x1000:
|
||||||
|
subpacket.DebugPrintSubPacket();
|
||||||
|
|
||||||
Actor ownerActor = Server.GetStaticActors(eventStart.ownerActorID);
|
SessionBeginPacket beginSessionPacket = new SessionBeginPacket(subpacket.data);
|
||||||
|
|
||||||
|
session = mServer.AddSession(subpacket.header.sourceId);
|
||||||
|
|
||||||
|
if (!beginSessionPacket.isLogin)
|
||||||
|
Server.GetWorldManager().DoZoneIn(session.GetActor(), false, session.GetActor().destinationSpawnType);
|
||||||
|
|
||||||
|
Program.Log.Info("{0} has been added to the session list.", session.GetActor().DisplayName);
|
||||||
|
|
||||||
|
client.FlushQueuedSendPackets();
|
||||||
|
break;
|
||||||
|
//World Server - Session End
|
||||||
|
case 0x1001:
|
||||||
|
SessionEndPacket endSessionPacket = new SessionEndPacket(subpacket.data);
|
||||||
|
|
||||||
|
if (endSessionPacket.destinationZoneId == 0)
|
||||||
|
session.GetActor().CleanupAndSave();
|
||||||
|
else
|
||||||
|
session.GetActor().CleanupAndSave(endSessionPacket.destinationZoneId, endSessionPacket.destinationSpawnType, endSessionPacket.destinationX, endSessionPacket.destinationY, endSessionPacket.destinationZ, endSessionPacket.destinationRot);
|
||||||
|
|
||||||
|
Server.GetServer().RemoveSession(session.id);
|
||||||
|
Program.Log.Info("{0} has been removed from the session list.", session.GetActor().DisplayName);
|
||||||
|
|
||||||
|
session.QueuePacket(SessionEndConfirmPacket.BuildPacket(session, endSessionPacket.destinationZoneId));
|
||||||
|
client.FlushQueuedSendPackets();
|
||||||
|
break;
|
||||||
|
//World Server - Party Synch
|
||||||
|
case 0x1020:
|
||||||
|
PartySyncPacket partySyncPacket = new PartySyncPacket(subpacket.data);
|
||||||
|
Server.GetWorldManager().PartyMemberListRecieved(partySyncPacket);
|
||||||
|
break;
|
||||||
|
//World Server - Linkshell Creation Result
|
||||||
|
case 0x1025:
|
||||||
|
LinkshellResultPacket lsResult = new LinkshellResultPacket(subpacket.data);
|
||||||
|
LuaEngine.GetInstance().OnSignal("ls_result", lsResult.resultCode);
|
||||||
|
break;
|
||||||
|
//Ping
|
||||||
|
case 0x0001:
|
||||||
|
//subpacket.DebugPrintSubPacket();
|
||||||
|
PingPacket pingPacket = new PingPacket(subpacket.data);
|
||||||
|
session.QueuePacket(PongPacket.BuildPacket(session.id, pingPacket.time));
|
||||||
|
session.Ping();
|
||||||
|
break;
|
||||||
|
//Unknown
|
||||||
|
case 0x0002:
|
||||||
|
|
||||||
|
subpacket.DebugPrintSubPacket();
|
||||||
|
session.QueuePacket(_0x2Packet.BuildPacket(session.id));
|
||||||
|
client.FlushQueuedSendPackets();
|
||||||
|
|
||||||
|
break;
|
||||||
|
//Chat Received
|
||||||
|
case 0x0003:
|
||||||
|
ChatMessagePacket chatMessage = new ChatMessagePacket(subpacket.data);
|
||||||
|
//Program.Log.Info("Got type-{5} message: {0} @ {1}, {2}, {3}, Rot: {4}", chatMessage.message, chatMessage.posX, chatMessage.posY, chatMessage.posZ, chatMessage.posRot, chatMessage.logType);
|
||||||
|
|
||||||
|
if (chatMessage.message.StartsWith("!"))
|
||||||
|
{
|
||||||
|
if (Server.GetCommandProcessor().DoCommand(chatMessage.message, session))
|
||||||
|
return; ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SAY || chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SHOUT)
|
||||||
|
session.GetActor().BroadcastPacket(SendMessagePacket.BuildPacket(session.id, chatMessage.logType, session.GetActor().DisplayName, chatMessage.message), false);
|
||||||
|
|
||||||
|
break;
|
||||||
|
//Langauge Code (Client safe to send packets to now)
|
||||||
|
case 0x0006:
|
||||||
|
LangaugeCodePacket langCode = new LangaugeCodePacket(subpacket.data);
|
||||||
|
LuaEngine.GetInstance().CallLuaFunction(session.GetActor(), session.GetActor(), "onBeginLogin", true);
|
||||||
|
Server.GetWorldManager().DoZoneIn(session.GetActor(), true, 0x1);
|
||||||
|
LuaEngine.GetInstance().CallLuaFunction(session.GetActor(), session.GetActor(), "onLogin", true);
|
||||||
|
session.languageCode = langCode.languageCode;
|
||||||
|
break;
|
||||||
|
//Unknown - Happens a lot at login, then once every time player zones
|
||||||
|
case 0x0007:
|
||||||
|
//subpacket.DebugPrintSubPacket();
|
||||||
|
ZoneInCompletePacket zoneInCompletePacket = new ZoneInCompletePacket(subpacket.data);
|
||||||
|
break;
|
||||||
|
//Update Position
|
||||||
|
case 0x00CA:
|
||||||
|
//Update Position
|
||||||
|
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
|
||||||
|
session.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
|
||||||
|
session.GetActor().SendInstanceUpdate();
|
||||||
|
|
||||||
|
if (session.GetActor().IsInZoneChange())
|
||||||
|
session.GetActor().SetZoneChanging(false);
|
||||||
|
|
||||||
|
break;
|
||||||
|
//Set Target
|
||||||
|
case 0x00CD:
|
||||||
|
//subpacket.DebugPrintSubPacket();
|
||||||
|
|
||||||
|
SetTargetPacket setTarget = new SetTargetPacket(subpacket.data);
|
||||||
|
session.GetActor().currentTarget = setTarget.actorID;
|
||||||
|
session.GetActor().isAutoAttackEnabled = setTarget.attackTarget != 0xE0000000;
|
||||||
|
session.GetActor().BroadcastPacket(SetActorTargetAnimatedPacket.BuildPacket(session.id, setTarget.actorID), true);
|
||||||
|
break;
|
||||||
|
//Lock Target
|
||||||
|
case 0x00CC:
|
||||||
|
LockTargetPacket lockTarget = new LockTargetPacket(subpacket.data);
|
||||||
|
session.GetActor().currentLockedTarget = lockTarget.actorID;
|
||||||
|
break;
|
||||||
|
//Start Event
|
||||||
|
case 0x012D:
|
||||||
|
subpacket.DebugPrintSubPacket();
|
||||||
|
EventStartPacket eventStart = new EventStartPacket(subpacket.data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (eventStart.error != null)
|
||||||
|
{
|
||||||
|
player.errorMessage += eventStart.error;
|
||||||
|
|
||||||
|
if (eventStart.errorIndex == eventStart.errorNum - 1)
|
||||||
|
Program.Log.Error("\n"+player.errorMessage);
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Actor ownerActor = Server.GetStaticActors(eventStart.ownerActorID);
|
||||||
|
|
||||||
|
if (ownerActor == null)
|
||||||
|
{
|
||||||
|
//Is it your retainer?
|
||||||
|
if (session.GetActor().currentSpawnedRetainer != null && session.GetActor().currentSpawnedRetainer.Id == eventStart.ownerActorID)
|
||||||
|
ownerActor = session.GetActor().currentSpawnedRetainer;
|
||||||
|
//Is it a instance actor?
|
||||||
|
if (ownerActor == null)
|
||||||
|
ownerActor = session.GetActor().CurrentArea.FindActorInArea(eventStart.ownerActorID);
|
||||||
|
//Is it a Director?
|
||||||
if (ownerActor == null)
|
if (ownerActor == null)
|
||||||
{
|
{
|
||||||
//Is it your retainer?
|
Director director = session.GetActor().GetDirector(eventStart.ownerActorID);
|
||||||
if (session.GetActor().currentSpawnedRetainer != null && session.GetActor().currentSpawnedRetainer.Id == eventStart.ownerActorID)
|
if (director != null)
|
||||||
ownerActor = session.GetActor().currentSpawnedRetainer;
|
ownerActor = director;
|
||||||
//Is it a instance actor?
|
else
|
||||||
if (ownerActor == null)
|
|
||||||
ownerActor = session.GetActor().CurrentArea.FindActorInArea(eventStart.ownerActorID);
|
|
||||||
//Is it a Director?
|
|
||||||
if (ownerActor == null)
|
|
||||||
{
|
{
|
||||||
Director director = session.GetActor().GetDirector(eventStart.ownerActorID);
|
Program.Log.Debug("\n===Event START===\nCould not find actor 0x{0:X} for event started by caller: 0x{1:X}\nEvent Starter: {2}\nParams: {3}", eventStart.triggerActorID, eventStart.ownerActorID, eventStart.eventName, LuaUtils.DumpParams(eventStart.luaParams));
|
||||||
if (director != null)
|
|
||||||
ownerActor = director;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Program.Log.Debug("\n===Event START===\nCould not find actor 0x{0:X} for event started by caller: 0x{1:X}\nEvent Starter: {2}\nParams: {3}", eventStart.triggerActorID, eventStart.ownerActorID, eventStart.eventName, LuaUtils.DumpParams(eventStart.luaParams));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
session.GetActor().StartEvent(ownerActor, eventStart);
|
|
||||||
|
|
||||||
Program.Log.Debug("\n===Event START===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nEvent Starter: {4}\nParams: {5}", eventStart.triggerActorID, eventStart.ownerActorID, eventStart.serverCodes, eventStart.unknown, eventStart.eventName, LuaUtils.DumpParams(eventStart.luaParams));
|
|
||||||
break;
|
|
||||||
//Unknown, happens at npc spawn and cutscene play????
|
|
||||||
case 0x00CE:
|
|
||||||
subpacket.DebugPrintSubPacket();
|
|
||||||
break;
|
|
||||||
//Countdown requested
|
|
||||||
case 0x00CF:
|
|
||||||
CountdownRequestPacket countdownPacket = new CountdownRequestPacket(subpacket.data);
|
|
||||||
session.GetActor().BroadcastCountdown(countdownPacket.countdownLength, countdownPacket.syncTime);
|
|
||||||
break;
|
|
||||||
//Event Result
|
|
||||||
case 0x012E:
|
|
||||||
subpacket.DebugPrintSubPacket();
|
|
||||||
EventUpdatePacket eventUpdate = new EventUpdatePacket(subpacket.data);
|
|
||||||
Program.Log.Debug("\n===Event UPDATE===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nStep: 0x{4:X}\nParams: {5}", eventUpdate.triggerActorID, eventUpdate.serverCodes, eventUpdate.unknown1, eventUpdate.unknown2, eventUpdate.eventType, LuaUtils.DumpParams(eventUpdate.luaParams));
|
|
||||||
/*
|
|
||||||
//Is it a static actor? If not look in the player's instance
|
|
||||||
Actor updateOwnerActor = Server.GetStaticActors(session.GetActor().currentEventOwner);
|
|
||||||
if (updateOwnerActor == null)
|
|
||||||
{
|
|
||||||
updateOwnerActor = Server.GetWorldManager().GetActorInWorld(session.GetActor().currentEventOwner);
|
|
||||||
|
|
||||||
if (session.GetActor().currentDirector != null && session.GetActor().currentEventOwner == session.GetActor().currentDirector.actorId)
|
|
||||||
updateOwnerActor = session.GetActor().currentDirector;
|
|
||||||
|
|
||||||
if (updateOwnerActor == null)
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
}
|
||||||
session.GetActor().UpdateEvent(eventUpdate);
|
|
||||||
|
|
||||||
//LuaEngine.DoActorOnEventUpdated(session.GetActor(), updateOwnerActor, eventUpdate);
|
session.GetActor().StartEvent(ownerActor, eventStart);
|
||||||
|
|
||||||
break;
|
Program.Log.Debug("\n===Event START===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nEvent Starter: {4}\nParams: {5}", eventStart.triggerActorID, eventStart.ownerActorID, eventStart.serverCodes, eventStart.unknown, eventStart.eventName, LuaUtils.DumpParams(eventStart.luaParams));
|
||||||
case 0x012F:
|
break;
|
||||||
subpacket.DebugPrintSubPacket();
|
//Unknown, happens at npc spawn and cutscene play????
|
||||||
ParameterDataRequestPacket paramRequest = new ParameterDataRequestPacket(subpacket.data);
|
case 0x00CE:
|
||||||
if (paramRequest.paramName.Equals("charaWork/exp"))
|
subpacket.DebugPrintSubPacket();
|
||||||
session.GetActor().SendCharaExpInfo();
|
break;
|
||||||
break;
|
//Countdown requested
|
||||||
//Item Package Request
|
case 0x00CF:
|
||||||
case 0x0131:
|
CountdownRequestPacket countdownPacket = new CountdownRequestPacket(subpacket.data);
|
||||||
UpdateItemPackagePacket packageRequest = new UpdateItemPackagePacket(subpacket.data);
|
session.GetActor().BroadcastCountdown(countdownPacket.countdownLength, countdownPacket.syncTime);
|
||||||
if (Server.GetWorldManager().GetActorInWorld(packageRequest.actorID) != null)
|
break;
|
||||||
{
|
//Event Result
|
||||||
((Character)Server.GetWorldManager().GetActorInWorld(packageRequest.actorID)).SendItemPackage(session.GetActor(), packageRequest.packageId);
|
case 0x012E:
|
||||||
|
subpacket.DebugPrintSubPacket();
|
||||||
|
EventUpdatePacket eventUpdate = new EventUpdatePacket(subpacket.data);
|
||||||
|
Program.Log.Debug("\n===Event UPDATE===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nStep: 0x{4:X}\nParams: {5}", eventUpdate.triggerActorID, eventUpdate.serverCodes, eventUpdate.unknown1, eventUpdate.unknown2, eventUpdate.eventType, LuaUtils.DumpParams(eventUpdate.luaParams));
|
||||||
|
/*
|
||||||
|
//Is it a static actor? If not look in the player's instance
|
||||||
|
Actor updateOwnerActor = Server.GetStaticActors(session.GetActor().currentEventOwner);
|
||||||
|
if (updateOwnerActor == null)
|
||||||
|
{
|
||||||
|
updateOwnerActor = Server.GetWorldManager().GetActorInWorld(session.GetActor().currentEventOwner);
|
||||||
|
|
||||||
|
if (session.GetActor().currentDirector != null && session.GetActor().currentEventOwner == session.GetActor().currentDirector.actorId)
|
||||||
|
updateOwnerActor = session.GetActor().currentDirector;
|
||||||
|
|
||||||
|
if (updateOwnerActor == null)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (session.GetActor().GetSpawnedRetainer() != null && session.GetActor().GetSpawnedRetainer().Id == packageRequest.actorID)
|
*/
|
||||||
session.GetActor().GetSpawnedRetainer().SendItemPackage(session.GetActor(), packageRequest.packageId);
|
session.GetActor().UpdateEvent(eventUpdate);
|
||||||
|
|
||||||
|
//LuaEngine.DoActorOnEventUpdated(session.GetActor(), updateOwnerActor, eventUpdate);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0x012F:
|
||||||
|
subpacket.DebugPrintSubPacket();
|
||||||
|
WorkSyncRequestPacket workSyncRequest = new WorkSyncRequestPacket(subpacket.data);
|
||||||
|
session.GetActor().OnWorkSyncRequest(workSyncRequest.propertyName, workSyncRequest.from, workSyncRequest.to);
|
||||||
|
break;
|
||||||
|
//Item Package Request
|
||||||
|
case 0x0131:
|
||||||
|
UpdateItemPackagePacket packageRequest = new UpdateItemPackagePacket(subpacket.data);
|
||||||
|
if (Server.GetWorldManager().GetActorInWorld(packageRequest.actorID) != null)
|
||||||
|
{
|
||||||
|
((Character)Server.GetWorldManager().GetActorInWorld(packageRequest.actorID)).SendItemPackage(session.GetActor(), packageRequest.packageId);
|
||||||
break;
|
break;
|
||||||
//Group Created Confirm
|
}
|
||||||
case 0x0133:
|
if (session.GetActor().GetSpawnedRetainer() != null && session.GetActor().GetSpawnedRetainer().Id == packageRequest.actorID)
|
||||||
GroupCreatedPacket groupCreated = new GroupCreatedPacket(subpacket.data);
|
session.GetActor().GetSpawnedRetainer().SendItemPackage(session.GetActor(), packageRequest.packageId);
|
||||||
Server.GetWorldManager().SendGroupInit(session, groupCreated.groupId);
|
break;
|
||||||
break;
|
//Group Created Confirm
|
||||||
//Achievement Progress Request
|
case 0x0133:
|
||||||
case 0x0135:
|
GroupCreatedPacket groupCreated = new GroupCreatedPacket(subpacket.data);
|
||||||
AchievementProgressRequestPacket progressRequest = new AchievementProgressRequestPacket(subpacket.data);
|
Server.GetWorldManager().SendGroupInit(session, groupCreated.groupId);
|
||||||
session.QueuePacket(Database.GetAchievementProgress(session.GetActor(), progressRequest.achievementId));
|
break;
|
||||||
break;
|
//Achievement Progress Request
|
||||||
/* RECRUITMENT */
|
case 0x0135:
|
||||||
//Start Recruiting
|
AchievementProgressRequestPacket progressRequest = new AchievementProgressRequestPacket(subpacket.data);
|
||||||
case 0x01C3:
|
session.QueuePacket(Database.GetAchievementProgress(session.GetActor(), progressRequest.achievementId));
|
||||||
StartRecruitingRequestPacket recruitRequestPacket = new StartRecruitingRequestPacket(subpacket.data);
|
break;
|
||||||
session.QueuePacket(StartRecruitingResponse.BuildPacket(session.id, true));
|
/* RECRUITMENT */
|
||||||
break;
|
//Start Recruiting
|
||||||
//End Recruiting
|
case 0x01C3:
|
||||||
case 0x01C4:
|
StartRecruitingRequestPacket recruitRequestPacket = new StartRecruitingRequestPacket(subpacket.data);
|
||||||
session.QueuePacket(EndRecruitmentPacket.BuildPacket(session.id));
|
session.QueuePacket(StartRecruitingResponse.BuildPacket(session.id, true));
|
||||||
break;
|
break;
|
||||||
//Party Window Opened, Request State
|
//End Recruiting
|
||||||
case 0x01C5:
|
case 0x01C4:
|
||||||
session.QueuePacket(RecruiterStatePacket.BuildPacket(session.id, false, false, 0));
|
session.QueuePacket(EndRecruitmentPacket.BuildPacket(session.id));
|
||||||
break;
|
break;
|
||||||
//Search Recruiting
|
//Party Window Opened, Request State
|
||||||
case 0x01C7:
|
case 0x01C5:
|
||||||
RecruitmentSearchRequestPacket recruitSearchPacket = new RecruitmentSearchRequestPacket(subpacket.data);
|
session.QueuePacket(RecruiterStatePacket.BuildPacket(session.id, false, false, 0));
|
||||||
break;
|
break;
|
||||||
//Get Recruitment Details
|
//Search Recruiting
|
||||||
case 0x01C8:
|
case 0x01C7:
|
||||||
RecruitmentDetailsRequestPacket currentRecruitDetailsPacket = new RecruitmentDetailsRequestPacket(subpacket.data);
|
RecruitmentSearchRequestPacket recruitSearchPacket = new RecruitmentSearchRequestPacket(subpacket.data);
|
||||||
RecruitmentDetails details = new RecruitmentDetails();
|
break;
|
||||||
details.recruiterName = "Localhost Character";
|
//Get Recruitment Details
|
||||||
details.purposeId = 2;
|
case 0x01C8:
|
||||||
details.locationId = 1;
|
RecruitmentDetailsRequestPacket currentRecruitDetailsPacket = new RecruitmentDetailsRequestPacket(subpacket.data);
|
||||||
details.subTaskId = 1;
|
RecruitmentDetails details = new RecruitmentDetails();
|
||||||
details.comment = "This is a test details packet sent by the server. No implementation has been Created yet...";
|
details.recruiterName = "Localhost Character";
|
||||||
details.num[0] = 1;
|
details.purposeId = 2;
|
||||||
session.QueuePacket(CurrentRecruitmentDetailsPacket.BuildPacket(session.id, details));
|
details.locationId = 1;
|
||||||
break;
|
details.subTaskId = 1;
|
||||||
//Accepted Recruiting
|
details.comment = "This is a test details packet sent by the server. No implementation has been Created yet...";
|
||||||
case 0x01C6:
|
details.num[0] = 1;
|
||||||
subpacket.DebugPrintSubPacket();
|
session.QueuePacket(CurrentRecruitmentDetailsPacket.BuildPacket(session.id, details));
|
||||||
break;
|
break;
|
||||||
/* SOCIAL STUFF */
|
//Accepted Recruiting
|
||||||
case 0x01C9:
|
case 0x01C6:
|
||||||
AddRemoveSocialPacket addBlackList = new AddRemoveSocialPacket(subpacket.data);
|
subpacket.DebugPrintSubPacket();
|
||||||
session.QueuePacket(BlacklistAddedPacket.BuildPacket(session.id, true, addBlackList.name));
|
break;
|
||||||
break;
|
/* SOCIAL STUFF */
|
||||||
case 0x01CA:
|
case 0x01C9:
|
||||||
AddRemoveSocialPacket RemoveBlackList = new AddRemoveSocialPacket(subpacket.data);
|
AddRemoveSocialPacket addBlackList = new AddRemoveSocialPacket(subpacket.data);
|
||||||
session.QueuePacket(BlacklistRemovedPacket.BuildPacket(session.id, true, RemoveBlackList.name));
|
session.QueuePacket(BlacklistAddedPacket.BuildPacket(session.id, true, addBlackList.name));
|
||||||
break;
|
break;
|
||||||
case 0x01CB:
|
case 0x01CA:
|
||||||
int offset1 = 0;
|
AddRemoveSocialPacket RemoveBlackList = new AddRemoveSocialPacket(subpacket.data);
|
||||||
session.QueuePacket(SendBlacklistPacket.BuildPacket(session.id, new String[] { "Test" }, ref offset1));
|
session.QueuePacket(BlacklistRemovedPacket.BuildPacket(session.id, true, RemoveBlackList.name));
|
||||||
break;
|
break;
|
||||||
case 0x01CC:
|
case 0x01CB:
|
||||||
AddRemoveSocialPacket addFriendList = new AddRemoveSocialPacket(subpacket.data);
|
int offset1 = 0;
|
||||||
session.QueuePacket(FriendlistAddedPacket.BuildPacket(session.id, true, (uint)addFriendList.name.GetHashCode(), true, addFriendList.name));
|
session.QueuePacket(SendBlacklistPacket.BuildPacket(session.id, new String[] { "Test" }, ref offset1));
|
||||||
break;
|
break;
|
||||||
case 0x01CD:
|
case 0x01CC:
|
||||||
AddRemoveSocialPacket RemoveFriendList = new AddRemoveSocialPacket(subpacket.data);
|
AddRemoveSocialPacket addFriendList = new AddRemoveSocialPacket(subpacket.data);
|
||||||
session.QueuePacket(FriendlistRemovedPacket.BuildPacket(session.id, true, RemoveFriendList.name));
|
session.QueuePacket(FriendlistAddedPacket.BuildPacket(session.id, true, (uint)addFriendList.name.GetHashCode(), true, addFriendList.name));
|
||||||
break;
|
break;
|
||||||
case 0x01CE:
|
case 0x01CD:
|
||||||
int offset2 = 0;
|
AddRemoveSocialPacket RemoveFriendList = new AddRemoveSocialPacket(subpacket.data);
|
||||||
session.QueuePacket(SendFriendlistPacket.BuildPacket(session.id, new Tuple<long, string>[] { new Tuple<long, string>(01, "Test2") }, ref offset2));
|
session.QueuePacket(FriendlistRemovedPacket.BuildPacket(session.id, true, RemoveFriendList.name));
|
||||||
break;
|
break;
|
||||||
case 0x01CF:
|
case 0x01CE:
|
||||||
session.QueuePacket(FriendStatusPacket.BuildPacket(session.id, null));
|
int offset2 = 0;
|
||||||
break;
|
session.QueuePacket(SendFriendlistPacket.BuildPacket(session.id, new Tuple<long, string>[] { new Tuple<long, string>(01, "Test2") }, ref offset2));
|
||||||
/* SUPPORT DESK STUFF */
|
break;
|
||||||
//Request for FAQ/Info List
|
case 0x01CF:
|
||||||
case 0x01D0:
|
session.QueuePacket(FriendStatusPacket.BuildPacket(session.id, null));
|
||||||
FaqListRequestPacket faqRequest = new FaqListRequestPacket(subpacket.data);
|
break;
|
||||||
session.QueuePacket(FaqListResponsePacket.BuildPacket(session.id, new string[] { "Testing FAQ1", "Coded style!" }));
|
/* SUPPORT DESK STUFF */
|
||||||
break;
|
//Request for FAQ/Info List
|
||||||
//Request for body of a faq/info selection
|
case 0x01D0:
|
||||||
case 0x01D1:
|
FaqListRequestPacket faqRequest = new FaqListRequestPacket(subpacket.data);
|
||||||
FaqBodyRequestPacket faqBodyRequest = new FaqBodyRequestPacket(subpacket.data);
|
session.QueuePacket(FaqListResponsePacket.BuildPacket(session.id, new string[] { "Testing FAQ1", "Coded style!" }));
|
||||||
session.QueuePacket(FaqBodyResponsePacket.BuildPacket(session.id, "HERE IS A GIANT BODY. Nothing else to say!"));
|
break;
|
||||||
break;
|
//Request for body of a faq/info selection
|
||||||
//Request issue list
|
case 0x01D1:
|
||||||
case 0x01D2:
|
FaqBodyRequestPacket faqBodyRequest = new FaqBodyRequestPacket(subpacket.data);
|
||||||
GMTicketIssuesRequestPacket issuesRequest = new GMTicketIssuesRequestPacket(subpacket.data);
|
session.QueuePacket(FaqBodyResponsePacket.BuildPacket(session.id, "HERE IS A GIANT BODY. Nothing else to say!"));
|
||||||
session.QueuePacket(IssueListResponsePacket.BuildPacket(session.id, new string[] { "Test1", "Test2", "Test3", "Test4", "Test5" }));
|
break;
|
||||||
break;
|
//Request issue list
|
||||||
//Request if GM ticket exists
|
case 0x01D2:
|
||||||
case 0x01D3:
|
GMTicketIssuesRequestPacket issuesRequest = new GMTicketIssuesRequestPacket(subpacket.data);
|
||||||
session.QueuePacket(StartGMTicketPacket.BuildPacket(session.id, false));
|
session.QueuePacket(IssueListResponsePacket.BuildPacket(session.id, new string[] { "Test1", "Test2", "Test3", "Test4", "Test5" }));
|
||||||
break;
|
break;
|
||||||
//Request for GM response message
|
//Request if GM ticket exists
|
||||||
case 0x01D4:
|
case 0x01D3:
|
||||||
session.QueuePacket(GMTicketPacket.BuildPacket(session.id, "This is a GM Ticket Title", "This is a GM Ticket Body."));
|
session.QueuePacket(StartGMTicketPacket.BuildPacket(session.id, false));
|
||||||
break;
|
break;
|
||||||
//GM Ticket Sent
|
//Request for GM response message
|
||||||
case 0x01D5:
|
case 0x01D4:
|
||||||
GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
|
session.QueuePacket(GMTicketPacket.BuildPacket(session.id, "This is a GM Ticket Title", "This is a GM Ticket Body."));
|
||||||
Program.Log.Info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
|
break;
|
||||||
session.QueuePacket(GMTicketSentResponsePacket.BuildPacket(session.id, true));
|
//GM Ticket Sent
|
||||||
break;
|
case 0x01D5:
|
||||||
//Request to end ticket
|
GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
|
||||||
case 0x01D6:
|
Program.Log.Info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
|
||||||
session.QueuePacket(EndGMTicketPacket.BuildPacket(session.id));
|
session.QueuePacket(GMTicketSentResponsePacket.BuildPacket(session.id, true));
|
||||||
break;
|
break;
|
||||||
default:
|
//Request to end ticket
|
||||||
Program.Log.Debug("Unknown command 0x{0:X} received.", subpacket.gameMessage.opcode);
|
case 0x01D6:
|
||||||
subpacket.DebugPrintSubPacket();
|
session.QueuePacket(EndGMTicketPacket.BuildPacket(session.id));
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
|
Program.Log.Debug("Unknown command 0x{0:X} received.", subpacket.gameMessage.opcode);
|
||||||
}
|
subpacket.DebugPrintSubPacket();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ using System.Text;
|
||||||
|
|
||||||
namespace Meteor.Map.packets.receive
|
namespace Meteor.Map.packets.receive
|
||||||
{
|
{
|
||||||
class ParameterDataRequestPacket
|
class WorkSyncRequestPacket
|
||||||
{
|
{
|
||||||
public const ushort OPCODE = 0x012F;
|
public const ushort OPCODE = 0x012F;
|
||||||
public const uint PACKET_SIZE = 0x48;
|
public const uint PACKET_SIZE = 0x48;
|
||||||
|
@ -34,9 +34,11 @@ namespace Meteor.Map.packets.receive
|
||||||
public bool invalidPacket = false;
|
public bool invalidPacket = false;
|
||||||
|
|
||||||
public uint actorID;
|
public uint actorID;
|
||||||
public string paramName;
|
public string propertyName;
|
||||||
|
public ushort from, to;
|
||||||
|
public bool requestingBitfield = false;
|
||||||
|
|
||||||
public ParameterDataRequestPacket(byte[] data)
|
public WorkSyncRequestPacket(byte[] data)
|
||||||
{
|
{
|
||||||
using (MemoryStream mem = new MemoryStream(data))
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
{
|
{
|
||||||
|
@ -44,13 +46,22 @@ namespace Meteor.Map.packets.receive
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
actorID = binReader.ReadUInt32();
|
actorID = binReader.ReadUInt32();
|
||||||
List<byte> strList = new List<byte>();
|
if (binReader.PeekChar() == 9)
|
||||||
byte curByte;
|
|
||||||
while ((curByte = binReader.ReadByte()) != 0 && strList.Count<=0x20)
|
|
||||||
{
|
{
|
||||||
strList.Add(curByte);
|
binReader.ReadByte();
|
||||||
|
from = binReader.ReadUInt16();
|
||||||
|
to = binReader.ReadUInt16();
|
||||||
}
|
}
|
||||||
paramName = Encoding.ASCII.GetString(strList.ToArray());
|
|
||||||
|
byte currentByte;
|
||||||
|
int size = 0;
|
||||||
|
long strPos = binReader.BaseStream.Position;
|
||||||
|
while ((currentByte = binReader.ReadByte()) != 0 && size <= 0x20)
|
||||||
|
size++;
|
||||||
|
|
||||||
|
binReader.BaseStream.Seek(strPos, SeekOrigin.Begin);
|
||||||
|
byte[] str = binReader.ReadBytes(size);
|
||||||
|
propertyName = Encoding.ASCII.GetString(str);
|
||||||
}
|
}
|
||||||
catch (Exception){
|
catch (Exception){
|
||||||
invalidPacket = true;
|
invalidPacket = true;
|
|
@ -44,6 +44,10 @@ namespace Meteor.Map.packets.send.actor
|
||||||
|
|
||||||
string currentTarget;
|
string currentTarget;
|
||||||
|
|
||||||
|
bool isBitfield = false;
|
||||||
|
ushort from;
|
||||||
|
ushort to;
|
||||||
|
|
||||||
private MemoryStream mem;
|
private MemoryStream mem;
|
||||||
private BinaryWriter binWriter;
|
private BinaryWriter binWriter;
|
||||||
|
|
||||||
|
@ -54,6 +58,16 @@ namespace Meteor.Map.packets.send.actor
|
||||||
binWriter.Seek(1, SeekOrigin.Begin);
|
binWriter.Seek(1, SeekOrigin.Begin);
|
||||||
currentTarget = startingTarget;
|
currentTarget = startingTarget;
|
||||||
}
|
}
|
||||||
|
public SetActorPropetyPacket(ushort from, ushort to, string startingTarget)
|
||||||
|
{
|
||||||
|
mem = new MemoryStream(data);
|
||||||
|
binWriter = new BinaryWriter(mem);
|
||||||
|
binWriter.Seek(1, SeekOrigin.Begin);
|
||||||
|
currentTarget = startingTarget;
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
isBitfield = true;
|
||||||
|
}
|
||||||
|
|
||||||
public void CloseStreams()
|
public void CloseStreams()
|
||||||
{
|
{
|
||||||
|
@ -100,6 +114,19 @@ namespace Meteor.Map.packets.send.actor
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AddBitfield(uint id, byte[] data)
|
||||||
|
{
|
||||||
|
if (runningByteTotal + 5 + data.Length + 1 + (1 + 5 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
binWriter.Write((byte) (data.Length));
|
||||||
|
binWriter.Write((UInt32)id);
|
||||||
|
binWriter.Write(data);
|
||||||
|
runningByteTotal += (ushort)(5 + data.Length);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool AddBuffer(uint id, byte[] buffer)
|
public bool AddBuffer(uint id, byte[] buffer)
|
||||||
{
|
{
|
||||||
if (runningByteTotal + 5 + buffer.Length + (1 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES)
|
if (runningByteTotal + 5 + buffer.Length + (1 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES)
|
||||||
|
@ -208,10 +235,22 @@ namespace Meteor.Map.packets.send.actor
|
||||||
public void SetTarget(string target)
|
public void SetTarget(string target)
|
||||||
{
|
{
|
||||||
currentTarget = target;
|
currentTarget = target;
|
||||||
|
isBitfield = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddTarget()
|
public void AddTarget()
|
||||||
{
|
{
|
||||||
|
if (isBitfield)
|
||||||
|
{
|
||||||
|
binWriter.Write((byte)(isMore ? 0x60 + currentTarget.Length + 5 : 0x82 + currentTarget.Length + 5));
|
||||||
|
binWriter.Write((byte)9);
|
||||||
|
binWriter.Write(from);
|
||||||
|
binWriter.Write(to);
|
||||||
|
binWriter.Write(Encoding.ASCII.GetBytes(currentTarget));
|
||||||
|
runningByteTotal += (ushort)(6 + Encoding.ASCII.GetByteCount(currentTarget));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isArrayMode)
|
if (isArrayMode)
|
||||||
binWriter.Write((byte)(0xA4 + currentTarget.Length));
|
binWriter.Write((byte)(0xA4 + currentTarget.Length));
|
||||||
else
|
else
|
||||||
|
@ -236,6 +275,7 @@ namespace Meteor.Map.packets.send.actor
|
||||||
CloseStreams();
|
CloseStreams();
|
||||||
|
|
||||||
SubPacket packet = new SubPacket(OPCODE, sourceActorId, data);
|
SubPacket packet = new SubPacket(OPCODE, sourceActorId, data);
|
||||||
|
packet.DebugPrintSubPacket();
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using Meteor.Common;
|
||||||
using MySql.Data.MySqlClient;
|
using MySql.Data.MySqlClient;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ namespace Meteor.Map
|
||||||
public static DateTime Tick = DateTime.Now;
|
public static DateTime Tick = DateTime.Now;
|
||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
// set up logging
|
// set up logging
|
||||||
Log = LogManager.GetCurrentClassLogger();
|
Log = LogManager.GetCurrentClassLogger();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
Loading…
Add table
Reference in a new issue