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
|
||||
{
|
||||
private readonly byte[] Data;
|
||||
private byte[] Data;
|
||||
|
||||
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)
|
||||
{
|
||||
return Get((int)at);
|
||||
|
@ -60,6 +66,7 @@ namespace Meteor.Common
|
|||
{
|
||||
int bytePos = at / 8;
|
||||
int bitPos = at % 8;
|
||||
|
||||
return (Data[bytePos] & (1 << bitPos)) != 0;
|
||||
}
|
||||
|
||||
|
@ -146,5 +153,46 @@ namespace Meteor.Common
|
|||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
var lookup = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
|
|
@ -74,7 +74,7 @@ function onTalk(player, quest, npc, eventName)
|
|||
-- Offer the quest
|
||||
if (npcClassId == KINNISON and not player:HasQuest(quest)) then
|
||||
local questAccepted = callClientFunction(player, "delegateEvent", player, quest, "processEventOffersStart");
|
||||
if (questAccepted) then
|
||||
if (questAccepted == 1) then
|
||||
player:AcceptQuest(quest);
|
||||
end
|
||||
player:EndEvent();
|
||||
|
@ -146,7 +146,7 @@ function onTalk(player, quest, npc, eventName)
|
|||
if (npcClassId == KINNISON) then
|
||||
callClientFunction(player, "delegateEvent", player, quest, "processEventClear");
|
||||
callClientFunction(player, "delegateEvent", player, quest, "sqrwa", 200, 1, 1, 9);
|
||||
player:CompleteQuest(quest:GetQuestId());
|
||||
player:CompleteQuest(quest);
|
||||
end
|
||||
end
|
||||
quest:UpdateENPCs();
|
||||
|
|
|
@ -47,6 +47,7 @@ using Meteor.Map.packets.send.actor.battle;
|
|||
using Meteor.Map.packets.receive.events;
|
||||
using static Meteor.Map.LuaUtils;
|
||||
using Meteor.Map.packets.send.actor.events;
|
||||
using System.Text;
|
||||
|
||||
namespace Meteor.Map.Actors
|
||||
{
|
||||
|
@ -244,7 +245,6 @@ namespace Meteor.Map.Actors
|
|||
|
||||
charaWork.commandAcquired[27150 - 26000] = true;
|
||||
|
||||
playerWork.questScenarioComplete[110001 - 110001] = true;
|
||||
playerWork.questGuildleveComplete[120050 - 120001] = true;
|
||||
|
||||
for (int i = 0; i < charaWork.additionalCommandAcquired.Length; i++ )
|
||||
|
@ -278,7 +278,7 @@ namespace Meteor.Map.Actors
|
|||
CalculateBaseStats();
|
||||
|
||||
questStateManager = new QuestStateManager(this);
|
||||
questStateManager.Init(questScenario);
|
||||
questStateManager.Init(questScenario, playerWork.questScenarioComplete);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
int max = 0;
|
||||
|
@ -1436,7 +1474,6 @@ namespace Meteor.Map.Actors
|
|||
|
||||
playerWork.questScenario[freeSlot] = instance.Id;
|
||||
questScenario[freeSlot] = instance;
|
||||
Database.SaveQuest(this, questScenario[freeSlot], freeSlot);
|
||||
SendQuestClientUpdate(freeSlot);
|
||||
|
||||
if (!isSilent)
|
||||
|
@ -1446,6 +1483,8 @@ namespace Meteor.Map.Actors
|
|||
|
||||
instance.OnAccept();
|
||||
|
||||
Database.SaveQuest(this, questScenario[freeSlot], freeSlot);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1458,8 +1497,11 @@ namespace Meteor.Map.Actors
|
|||
{
|
||||
questScenario[i] = newQuestInstance;
|
||||
playerWork.questScenario[i] = questScenario[i].Id;
|
||||
Database.SaveQuest(this, questScenario[i], i);
|
||||
SendQuestClientUpdate(i);
|
||||
oldQuestInstance.OnComplete();
|
||||
questStateManager.UpdateQuestCompleted(oldQuestInstance);
|
||||
newQuestInstance.OnAccept();
|
||||
Database.SaveQuest(this, questScenario[i], i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1472,14 +1514,14 @@ namespace Meteor.Map.Actors
|
|||
{
|
||||
// Remove the quest from the DB and update client work values
|
||||
playerWork.questScenarioComplete[completed.GetQuestId() - 110001] = true;
|
||||
Database.CompleteQuest(playerSession.GetActor(), completed.Id);
|
||||
Database.RemoveQuest(this, completed.Id);
|
||||
questScenario[slot] = null;
|
||||
playerWork.questScenario[slot] = 0;
|
||||
SendQuestClientUpdate(slot);
|
||||
|
||||
// Reset active quest and quest state
|
||||
completed.OnComplete();
|
||||
Database.SaveCompletedQuests(playerSession.GetActor());
|
||||
Database.RemoveQuest(this, completed.Id);
|
||||
questStateManager.UpdateQuestCompleted(completed);
|
||||
|
||||
// Msg Player
|
||||
|
@ -1512,13 +1554,13 @@ namespace Meteor.Map.Actors
|
|||
}
|
||||
|
||||
// Remove the quest from the DB and update client work values
|
||||
Database.RemoveQuest(this, abandoned.Id);
|
||||
questScenario[slot] = null;
|
||||
playerWork.questScenario[slot] = 0;
|
||||
SendQuestClientUpdate(slot);
|
||||
|
||||
// Reset active quest and quest state
|
||||
abandoned.OnAbandon();
|
||||
Database.RemoveQuest(this, abandoned.Id);
|
||||
questStateManager.UpdateQuestAbandoned();
|
||||
|
||||
// Msg Player
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace Meteor.Map.Actors.QuestNS
|
|||
private const int SCENARIO_MAX = 2048;
|
||||
|
||||
private readonly Player player;
|
||||
private readonly Bitstream CompletedQuestsBitfield = new Bitstream(SCENARIO_MAX);
|
||||
private readonly Bitstream AvailableQuestsBitfield = new Bitstream(SCENARIO_MAX);
|
||||
private readonly Bitstream MinLevelBitfield = new Bitstream(SCENARIO_MAX);
|
||||
private readonly Bitstream PrereqBitfield = new Bitstream(SCENARIO_MAX, true);
|
||||
|
@ -28,12 +29,12 @@ namespace Meteor.Map.Actors.QuestNS
|
|||
this.player = player;
|
||||
}
|
||||
|
||||
public void Init(Quest[] questScenario)
|
||||
public void Init(Quest[] journalQuests, bool[] completedQuests)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
|
@ -49,10 +50,10 @@ namespace Meteor.Map.Actors.QuestNS
|
|||
MinLevelBitfield.Set(questData.Id - SCENARIO_START);
|
||||
|
||||
// Init Prereq
|
||||
Bitstream completed = new Bitstream(player.playerWork.questScenarioComplete);
|
||||
CompletedQuestsBitfield.SetTo(completedQuests);
|
||||
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);
|
||||
else
|
||||
PrereqBitfield.Clear(questData.Id - SCENARIO_START);
|
||||
|
@ -71,6 +72,7 @@ namespace Meteor.Map.Actors.QuestNS
|
|||
|
||||
public void UpdateQuestCompleted(Quest quest)
|
||||
{
|
||||
CompletedQuestsBitfield.Set(quest.Id - SCENARIO_START);
|
||||
QuestGameData[] updated = Server.GetQuestGamedataByPrerequisite(quest.GetQuestId());
|
||||
foreach (var questData in updated)
|
||||
PrereqBitfield.Set(questData.Id - SCENARIO_START);
|
||||
|
@ -84,7 +86,8 @@ namespace Meteor.Map.Actors.QuestNS
|
|||
|
||||
private void ComputeAvailable()
|
||||
{
|
||||
Bitstream result = new Bitstream(player.playerWork.questScenarioComplete);
|
||||
Bitstream result = new Bitstream(SCENARIO_MAX);
|
||||
result.OR(CompletedQuestsBitfield);
|
||||
result.NOT();
|
||||
result.AND(MinLevelBitfield);
|
||||
result.AND(PrereqBitfield);
|
||||
|
@ -152,5 +155,10 @@ namespace Meteor.Map.Actors.QuestNS
|
|||
{
|
||||
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;
|
||||
MySqlCommand cmd;
|
||||
|
@ -776,15 +776,15 @@ namespace Meteor.Map
|
|||
|
||||
query = @"
|
||||
INSERT INTO characters_quest_completed
|
||||
(characterId, questId)
|
||||
(characterId, completedQuests)
|
||||
VALUES
|
||||
(@charaId, @questId)
|
||||
ON DUPLICATE KEY UPDATE characterId=characterId
|
||||
(@charaId, @completedQuests)
|
||||
ON DUPLICATE KEY UPDATE completedQuests=completedQuests
|
||||
";
|
||||
|
||||
cmd = new MySqlCommand(query, conn);
|
||||
cmd.Parameters.AddWithValue("@charaId", player.Id);
|
||||
cmd.Parameters.AddWithValue("@questId", 0xFFFFF & questId);
|
||||
cmd.Parameters.AddWithValue("@completedQuests", Utils.ConvertBoolArrayToBinaryStream(player.playerWork.questScenarioComplete));
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
query = @"
|
||||
SELECT
|
||||
|
|
|
@ -227,7 +227,7 @@
|
|||
<Compile Include="Packets\Receive\CountdownRequestPacket.cs" />
|
||||
<Compile Include="Packets\Receive\LangaugeCodePacket.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\RecruitmentSearchRequestPacket.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.Receive;
|
||||
using Meteor.Map.actors.director;
|
||||
using System.Text;
|
||||
|
||||
namespace Meteor.Map
|
||||
{
|
||||
|
@ -260,9 +261,8 @@ namespace Meteor.Map
|
|||
break;
|
||||
case 0x012F:
|
||||
subpacket.DebugPrintSubPacket();
|
||||
ParameterDataRequestPacket paramRequest = new ParameterDataRequestPacket(subpacket.data);
|
||||
if (paramRequest.paramName.Equals("charaWork/exp"))
|
||||
session.GetActor().SendCharaExpInfo();
|
||||
WorkSyncRequestPacket workSyncRequest = new WorkSyncRequestPacket(subpacket.data);
|
||||
session.GetActor().OnWorkSyncRequest(workSyncRequest.propertyName, workSyncRequest.from, workSyncRequest.to);
|
||||
break;
|
||||
//Item Package Request
|
||||
case 0x0131:
|
||||
|
|
|
@ -26,7 +26,7 @@ using System.Text;
|
|||
|
||||
namespace Meteor.Map.packets.receive
|
||||
{
|
||||
class ParameterDataRequestPacket
|
||||
class WorkSyncRequestPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x012F;
|
||||
public const uint PACKET_SIZE = 0x48;
|
||||
|
@ -34,9 +34,11 @@ namespace Meteor.Map.packets.receive
|
|||
public bool invalidPacket = false;
|
||||
|
||||
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))
|
||||
{
|
||||
|
@ -44,13 +46,22 @@ namespace Meteor.Map.packets.receive
|
|||
{
|
||||
try{
|
||||
actorID = binReader.ReadUInt32();
|
||||
List<byte> strList = new List<byte>();
|
||||
byte curByte;
|
||||
while ((curByte = binReader.ReadByte()) != 0 && strList.Count<=0x20)
|
||||
if (binReader.PeekChar() == 9)
|
||||
{
|
||||
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){
|
||||
invalidPacket = true;
|
|
@ -44,6 +44,10 @@ namespace Meteor.Map.packets.send.actor
|
|||
|
||||
string currentTarget;
|
||||
|
||||
bool isBitfield = false;
|
||||
ushort from;
|
||||
ushort to;
|
||||
|
||||
private MemoryStream mem;
|
||||
private BinaryWriter binWriter;
|
||||
|
||||
|
@ -54,6 +58,16 @@ namespace Meteor.Map.packets.send.actor
|
|||
binWriter.Seek(1, SeekOrigin.Begin);
|
||||
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()
|
||||
{
|
||||
|
@ -100,6 +114,19 @@ namespace Meteor.Map.packets.send.actor
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
currentTarget = target;
|
||||
isBitfield = false;
|
||||
}
|
||||
|
||||
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)
|
||||
binWriter.Write((byte)(0xA4 + currentTarget.Length));
|
||||
else
|
||||
|
@ -236,6 +275,7 @@ namespace Meteor.Map.packets.send.actor
|
|||
CloseStreams();
|
||||
|
||||
SubPacket packet = new SubPacket(OPCODE, sourceActorId, data);
|
||||
packet.DebugPrintSubPacket();
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
|||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Meteor.Common;
|
||||
using MySql.Data.MySqlClient;
|
||||
using NLog;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue