Removed all old Serialization tags and methods Potentially Breaking Change: Removed InventoryNode.ParentID - This was an old serlization hack. Use Data.ParentUUID instead
82712 lines
2.8 MiB
82712 lines
2.8 MiB
/*
|
|
* Copyright (c) 2006-2016, openmetaverse.co
|
|
* All rights reserved.
|
|
*
|
|
* - Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
* - Neither the name of the Second Life Reverse Engineering Team nor the names
|
|
* of its contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
using System;
|
|
using System.Text;
|
|
using OpenMetaverse;
|
|
|
|
namespace OpenMetaverse
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public enum PacketFrequency : byte
|
|
{
|
|
/// <summary></summary>
|
|
Low,
|
|
/// <summary></summary>
|
|
Medium,
|
|
/// <summary></summary>
|
|
High
|
|
}
|
|
}
|
|
|
|
namespace OpenMetaverse.Packets
|
|
{
|
|
/// <summary>
|
|
/// Thrown when a packet could not be successfully deserialized
|
|
/// </summary>
|
|
public class MalformedDataException : ApplicationException
|
|
{
|
|
/// <summary>
|
|
/// Default constructor
|
|
/// </summary>
|
|
public MalformedDataException() { }
|
|
|
|
/// <summary>
|
|
/// Constructor that takes an additional error message
|
|
/// </summary>
|
|
/// <param name="Message">An error message to attach to this exception</param>
|
|
public MalformedDataException(string Message)
|
|
: base(Message)
|
|
{
|
|
this.Source = "Packet decoding";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The header of a message template packet. Holds packet flags, sequence
|
|
/// number, packet ID, and any ACKs that will be appended at the end of
|
|
/// the packet
|
|
/// </summary>
|
|
public struct Header
|
|
{
|
|
public bool Reliable;
|
|
public bool Resent;
|
|
public bool Zerocoded;
|
|
public bool AppendedAcks;
|
|
public uint Sequence;
|
|
public ushort ID;
|
|
public PacketFrequency Frequency;
|
|
public uint[] AckList;
|
|
|
|
public void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
byte flags = 0;
|
|
if (Reliable) flags |= Helpers.MSG_RELIABLE;
|
|
if (Resent) flags |= Helpers.MSG_RESENT;
|
|
if (Zerocoded) flags |= Helpers.MSG_ZEROCODED;
|
|
if (AppendedAcks) flags |= Helpers.MSG_APPENDED_ACKS;
|
|
|
|
// Flags
|
|
bytes[i++] = flags;
|
|
|
|
// Sequence number
|
|
Utils.UIntToBytesBig(Sequence, bytes, i);
|
|
i += 4;
|
|
|
|
// Extra byte
|
|
bytes[i++] = 0;
|
|
|
|
// Packet ID
|
|
switch (Frequency)
|
|
{
|
|
case PacketFrequency.High:
|
|
// 1 byte ID
|
|
bytes[i++] = (byte)ID;
|
|
break;
|
|
case PacketFrequency.Medium:
|
|
// 2 byte ID
|
|
bytes[i++] = 0xFF;
|
|
bytes[i++] = (byte)ID;
|
|
break;
|
|
case PacketFrequency.Low:
|
|
// 4 byte ID
|
|
bytes[i++] = 0xFF;
|
|
bytes[i++] = 0xFF;
|
|
Utils.UInt16ToBytesBig(ID, bytes, i);
|
|
i += 2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void FromBytes(byte[] bytes, ref int pos, ref int packetEnd)
|
|
{
|
|
this = BuildHeader(bytes, ref pos, ref packetEnd);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert the AckList to a byte array, used for packet serializing
|
|
/// </summary>
|
|
/// <param name="bytes">Reference to the target byte array</param>
|
|
/// <param name="i">Beginning position to start writing to in the byte
|
|
/// array, will be updated with the ending position of the ACK list</param>
|
|
public void AcksToBytes(byte[] bytes, ref int i)
|
|
{
|
|
foreach (uint ack in AckList)
|
|
{
|
|
Utils.UIntToBytesBig(ack, bytes, i);
|
|
i += 4;
|
|
}
|
|
if (AckList.Length > 0) { bytes[i++] = (byte)AckList.Length; }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="bytes"></param>
|
|
/// <param name="pos"></param>
|
|
/// <param name="packetEnd"></param>
|
|
/// <returns></returns>
|
|
public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetEnd)
|
|
{
|
|
Header header;
|
|
byte flags = bytes[pos];
|
|
|
|
header.AppendedAcks = (flags & Helpers.MSG_APPENDED_ACKS) != 0;
|
|
header.Reliable = (flags & Helpers.MSG_RELIABLE) != 0;
|
|
header.Resent = (flags & Helpers.MSG_RESENT) != 0;
|
|
header.Zerocoded = (flags & Helpers.MSG_ZEROCODED) != 0;
|
|
header.Sequence = (uint)((bytes[pos + 1] << 24) + (bytes[pos + 2] << 16) + (bytes[pos + 3] << 8) + bytes[pos + 4]);
|
|
|
|
// Set the frequency and packet ID number
|
|
if (bytes[pos + 6] == 0xFF)
|
|
{
|
|
if (bytes[pos + 7] == 0xFF)
|
|
{
|
|
header.Frequency = PacketFrequency.Low;
|
|
if (header.Zerocoded && bytes[pos + 8] == 0)
|
|
header.ID = bytes[pos + 10];
|
|
else
|
|
header.ID = (ushort)((bytes[pos + 8] << 8) + bytes[pos + 9]);
|
|
|
|
pos += 10;
|
|
}
|
|
else
|
|
{
|
|
header.Frequency = PacketFrequency.Medium;
|
|
header.ID = bytes[pos + 7];
|
|
|
|
pos += 8;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
header.Frequency = PacketFrequency.High;
|
|
header.ID = bytes[pos + 6];
|
|
|
|
pos += 7;
|
|
}
|
|
|
|
header.AckList = null;
|
|
CreateAckList(ref header, bytes, ref packetEnd);
|
|
|
|
return header;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="header"></param>
|
|
/// <param name="bytes"></param>
|
|
/// <param name="packetEnd"></param>
|
|
static void CreateAckList(ref Header header, byte[] bytes, ref int packetEnd)
|
|
{
|
|
if (header.AppendedAcks)
|
|
{
|
|
int count = bytes[packetEnd--];
|
|
header.AckList = new uint[count];
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
header.AckList[i] = (uint)(
|
|
(bytes[(packetEnd - i * 4) - 3] << 24) |
|
|
(bytes[(packetEnd - i * 4) - 2] << 16) |
|
|
(bytes[(packetEnd - i * 4) - 1] << 8) |
|
|
(bytes[(packetEnd - i * 4) ]));
|
|
}
|
|
|
|
packetEnd -= (count * 4);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A block of data in a packet. Packets are composed of one or more blocks,
|
|
/// each block containing one or more fields
|
|
/// </summary>
|
|
public abstract class PacketBlock
|
|
{
|
|
/// <summary>Current length of the data in this packet</summary>
|
|
public abstract int Length { get; }
|
|
|
|
/// <summary>
|
|
/// Create a block from a byte array
|
|
/// </summary>
|
|
/// <param name="bytes">Byte array containing the serialized block</param>
|
|
/// <param name="i">Starting position of the block in the byte array.
|
|
/// This will point to the data after the end of the block when the
|
|
/// call returns</param>
|
|
public abstract void FromBytes(byte[] bytes, ref int i);
|
|
|
|
/// <summary>
|
|
/// Serialize this block into a byte array
|
|
/// </summary>
|
|
/// <param name="bytes">Byte array to serialize this block into</param>
|
|
/// <param name="i">Starting position in the byte array to serialize to.
|
|
/// This will point to the position directly after the end of the
|
|
/// serialized block when the call returns</param>
|
|
public abstract void ToBytes(byte[] bytes, ref int i);
|
|
}
|
|
|
|
public enum PacketType
|
|
{
|
|
/// <summary>A generic value, not an actual packet type</summary>
|
|
Default,
|
|
TestMessage = 65537,
|
|
UseCircuitCode = 65539,
|
|
TelehubInfo = 65546,
|
|
EconomyDataRequest = 65560,
|
|
EconomyData = 65561,
|
|
AvatarPickerRequest = 65562,
|
|
AvatarPickerReply = 65564,
|
|
PlacesQuery = 65565,
|
|
PlacesReply = 65566,
|
|
DirFindQuery = 65567,
|
|
DirPlacesQuery = 65569,
|
|
DirPlacesReply = 65571,
|
|
DirPeopleReply = 65572,
|
|
DirEventsReply = 65573,
|
|
DirGroupsReply = 65574,
|
|
DirClassifiedQuery = 65575,
|
|
DirClassifiedReply = 65577,
|
|
AvatarClassifiedReply = 65578,
|
|
ClassifiedInfoRequest = 65579,
|
|
ClassifiedInfoReply = 65580,
|
|
ClassifiedInfoUpdate = 65581,
|
|
ClassifiedDelete = 65582,
|
|
ClassifiedGodDelete = 65583,
|
|
DirLandQuery = 65584,
|
|
DirLandReply = 65586,
|
|
DirPopularQuery = 65587,
|
|
DirPopularReply = 65589,
|
|
ParcelInfoRequest = 65590,
|
|
ParcelInfoReply = 65591,
|
|
ParcelObjectOwnersRequest = 65592,
|
|
ParcelObjectOwnersReply = 65593,
|
|
GroupNoticesListRequest = 65594,
|
|
GroupNoticesListReply = 65595,
|
|
GroupNoticeRequest = 65596,
|
|
TeleportRequest = 65598,
|
|
TeleportLocationRequest = 65599,
|
|
TeleportLocal = 65600,
|
|
TeleportLandmarkRequest = 65601,
|
|
TeleportProgress = 65602,
|
|
TeleportFinish = 65605,
|
|
StartLure = 65606,
|
|
TeleportLureRequest = 65607,
|
|
TeleportCancel = 65608,
|
|
TeleportStart = 65609,
|
|
TeleportFailed = 65610,
|
|
Undo = 65611,
|
|
Redo = 65612,
|
|
UndoLand = 65613,
|
|
AgentPause = 65614,
|
|
AgentResume = 65615,
|
|
ChatFromViewer = 65616,
|
|
AgentThrottle = 65617,
|
|
AgentFOV = 65618,
|
|
AgentHeightWidth = 65619,
|
|
AgentSetAppearance = 65620,
|
|
AgentQuitCopy = 65621,
|
|
ImageNotInDatabase = 65622,
|
|
RebakeAvatarTextures = 65623,
|
|
SetAlwaysRun = 65624,
|
|
ObjectDelete = 65625,
|
|
ObjectDuplicate = 65626,
|
|
ObjectDuplicateOnRay = 65627,
|
|
ObjectScale = 65628,
|
|
ObjectRotation = 65629,
|
|
ObjectFlagUpdate = 65630,
|
|
ObjectClickAction = 65631,
|
|
ObjectImage = 65632,
|
|
ObjectMaterial = 65633,
|
|
ObjectShape = 65634,
|
|
ObjectExtraParams = 65635,
|
|
ObjectOwner = 65636,
|
|
ObjectGroup = 65637,
|
|
ObjectBuy = 65638,
|
|
BuyObjectInventory = 65639,
|
|
DerezContainer = 65640,
|
|
ObjectPermissions = 65641,
|
|
ObjectSaleInfo = 65642,
|
|
ObjectName = 65643,
|
|
ObjectDescription = 65644,
|
|
ObjectCategory = 65645,
|
|
ObjectSelect = 65646,
|
|
ObjectDeselect = 65647,
|
|
ObjectAttach = 65648,
|
|
ObjectDetach = 65649,
|
|
ObjectDrop = 65650,
|
|
ObjectLink = 65651,
|
|
ObjectDelink = 65652,
|
|
ObjectGrab = 65653,
|
|
ObjectGrabUpdate = 65654,
|
|
ObjectDeGrab = 65655,
|
|
ObjectSpinStart = 65656,
|
|
ObjectSpinUpdate = 65657,
|
|
ObjectSpinStop = 65658,
|
|
ObjectExportSelected = 65659,
|
|
ModifyLand = 65660,
|
|
VelocityInterpolateOn = 65661,
|
|
VelocityInterpolateOff = 65662,
|
|
StateSave = 65663,
|
|
ReportAutosaveCrash = 65664,
|
|
SimWideDeletes = 65665,
|
|
TrackAgent = 65666,
|
|
ViewerStats = 65667,
|
|
ScriptAnswerYes = 65668,
|
|
UserReport = 65669,
|
|
AlertMessage = 65670,
|
|
AgentAlertMessage = 65671,
|
|
MeanCollisionAlert = 65672,
|
|
ViewerFrozenMessage = 65673,
|
|
HealthMessage = 65674,
|
|
ChatFromSimulator = 65675,
|
|
SimStats = 65676,
|
|
RequestRegionInfo = 65677,
|
|
RegionInfo = 65678,
|
|
GodUpdateRegionInfo = 65679,
|
|
RegionHandshake = 65684,
|
|
RegionHandshakeReply = 65685,
|
|
SimulatorViewerTimeMessage = 65686,
|
|
EnableSimulator = 65687,
|
|
DisableSimulator = 65688,
|
|
TransferRequest = 65689,
|
|
TransferInfo = 65690,
|
|
TransferAbort = 65691,
|
|
RequestXfer = 65692,
|
|
AbortXfer = 65693,
|
|
AvatarAppearance = 65694,
|
|
SetFollowCamProperties = 65695,
|
|
ClearFollowCamProperties = 65696,
|
|
RequestPayPrice = 65697,
|
|
PayPriceReply = 65698,
|
|
KickUser = 65699,
|
|
GodKickUser = 65701,
|
|
EjectUser = 65703,
|
|
FreezeUser = 65704,
|
|
AvatarPropertiesRequest = 65705,
|
|
AvatarPropertiesReply = 65707,
|
|
AvatarInterestsReply = 65708,
|
|
AvatarGroupsReply = 65709,
|
|
AvatarPropertiesUpdate = 65710,
|
|
AvatarInterestsUpdate = 65711,
|
|
AvatarNotesReply = 65712,
|
|
AvatarNotesUpdate = 65713,
|
|
AvatarPicksReply = 65714,
|
|
EventInfoRequest = 65715,
|
|
EventInfoReply = 65716,
|
|
EventNotificationAddRequest = 65717,
|
|
EventNotificationRemoveRequest = 65718,
|
|
EventGodDelete = 65719,
|
|
PickInfoReply = 65720,
|
|
PickInfoUpdate = 65721,
|
|
PickDelete = 65722,
|
|
PickGodDelete = 65723,
|
|
ScriptQuestion = 65724,
|
|
ScriptControlChange = 65725,
|
|
ScriptDialog = 65726,
|
|
ScriptDialogReply = 65727,
|
|
ForceScriptControlRelease = 65728,
|
|
RevokePermissions = 65729,
|
|
LoadURL = 65730,
|
|
ScriptTeleportRequest = 65731,
|
|
ParcelOverlay = 65732,
|
|
ParcelPropertiesRequestByID = 65733,
|
|
ParcelPropertiesUpdate = 65734,
|
|
ParcelReturnObjects = 65735,
|
|
ParcelSetOtherCleanTime = 65736,
|
|
ParcelDisableObjects = 65737,
|
|
ParcelSelectObjects = 65738,
|
|
EstateCovenantRequest = 65739,
|
|
EstateCovenantReply = 65740,
|
|
ForceObjectSelect = 65741,
|
|
ParcelBuyPass = 65742,
|
|
ParcelDeedToGroup = 65743,
|
|
ParcelReclaim = 65744,
|
|
ParcelClaim = 65745,
|
|
ParcelJoin = 65746,
|
|
ParcelDivide = 65747,
|
|
ParcelRelease = 65748,
|
|
ParcelBuy = 65749,
|
|
ParcelGodForceOwner = 65750,
|
|
ParcelAccessListRequest = 65751,
|
|
ParcelAccessListReply = 65752,
|
|
ParcelAccessListUpdate = 65753,
|
|
ParcelDwellRequest = 65754,
|
|
ParcelDwellReply = 65755,
|
|
ParcelGodMarkAsContent = 65763,
|
|
ViewerStartAuction = 65764,
|
|
UUIDNameRequest = 65771,
|
|
UUIDNameReply = 65772,
|
|
UUIDGroupNameRequest = 65773,
|
|
UUIDGroupNameReply = 65774,
|
|
ChildAgentDying = 65776,
|
|
ChildAgentUnknown = 65777,
|
|
GetScriptRunning = 65779,
|
|
ScriptRunningReply = 65780,
|
|
SetScriptRunning = 65781,
|
|
ScriptReset = 65782,
|
|
ScriptSensorRequest = 65783,
|
|
ScriptSensorReply = 65784,
|
|
CompleteAgentMovement = 65785,
|
|
AgentMovementComplete = 65786,
|
|
LogoutRequest = 65788,
|
|
LogoutReply = 65789,
|
|
ImprovedInstantMessage = 65790,
|
|
RetrieveInstantMessages = 65791,
|
|
FindAgent = 65792,
|
|
RequestGodlikePowers = 65793,
|
|
GrantGodlikePowers = 65794,
|
|
GodlikeMessage = 65795,
|
|
EstateOwnerMessage = 65796,
|
|
GenericMessage = 65797,
|
|
MuteListRequest = 65798,
|
|
UpdateMuteListEntry = 65799,
|
|
RemoveMuteListEntry = 65800,
|
|
CopyInventoryFromNotecard = 65801,
|
|
UpdateInventoryItem = 65802,
|
|
UpdateCreateInventoryItem = 65803,
|
|
MoveInventoryItem = 65804,
|
|
CopyInventoryItem = 65805,
|
|
RemoveInventoryItem = 65806,
|
|
ChangeInventoryItemFlags = 65807,
|
|
SaveAssetIntoInventory = 65808,
|
|
CreateInventoryFolder = 65809,
|
|
UpdateInventoryFolder = 65810,
|
|
MoveInventoryFolder = 65811,
|
|
RemoveInventoryFolder = 65812,
|
|
FetchInventoryDescendents = 65813,
|
|
InventoryDescendents = 65814,
|
|
FetchInventory = 65815,
|
|
FetchInventoryReply = 65816,
|
|
BulkUpdateInventory = 65817,
|
|
RemoveInventoryObjects = 65820,
|
|
PurgeInventoryDescendents = 65821,
|
|
UpdateTaskInventory = 65822,
|
|
RemoveTaskInventory = 65823,
|
|
MoveTaskInventory = 65824,
|
|
RequestTaskInventory = 65825,
|
|
ReplyTaskInventory = 65826,
|
|
DeRezObject = 65827,
|
|
DeRezAck = 65828,
|
|
RezObject = 65829,
|
|
RezObjectFromNotecard = 65830,
|
|
AcceptFriendship = 65833,
|
|
DeclineFriendship = 65834,
|
|
TerminateFriendship = 65836,
|
|
OfferCallingCard = 65837,
|
|
AcceptCallingCard = 65838,
|
|
DeclineCallingCard = 65839,
|
|
RezScript = 65840,
|
|
CreateInventoryItem = 65841,
|
|
CreateLandmarkForEvent = 65842,
|
|
RegionHandleRequest = 65845,
|
|
RegionIDAndHandleReply = 65846,
|
|
MoneyTransferRequest = 65847,
|
|
MoneyBalanceRequest = 65849,
|
|
MoneyBalanceReply = 65850,
|
|
RoutedMoneyBalanceReply = 65851,
|
|
ActivateGestures = 65852,
|
|
DeactivateGestures = 65853,
|
|
MuteListUpdate = 65854,
|
|
UseCachedMuteList = 65855,
|
|
GrantUserRights = 65856,
|
|
ChangeUserRights = 65857,
|
|
OnlineNotification = 65858,
|
|
OfflineNotification = 65859,
|
|
SetStartLocationRequest = 65860,
|
|
AssetUploadRequest = 65869,
|
|
AssetUploadComplete = 65870,
|
|
CreateGroupRequest = 65875,
|
|
CreateGroupReply = 65876,
|
|
UpdateGroupInfo = 65877,
|
|
GroupRoleChanges = 65878,
|
|
JoinGroupRequest = 65879,
|
|
JoinGroupReply = 65880,
|
|
EjectGroupMemberRequest = 65881,
|
|
EjectGroupMemberReply = 65882,
|
|
LeaveGroupRequest = 65883,
|
|
LeaveGroupReply = 65884,
|
|
InviteGroupRequest = 65885,
|
|
GroupProfileRequest = 65887,
|
|
GroupProfileReply = 65888,
|
|
GroupAccountSummaryRequest = 65889,
|
|
GroupAccountSummaryReply = 65890,
|
|
GroupAccountDetailsRequest = 65891,
|
|
GroupAccountDetailsReply = 65892,
|
|
GroupAccountTransactionsRequest = 65893,
|
|
GroupAccountTransactionsReply = 65894,
|
|
GroupActiveProposalsRequest = 65895,
|
|
GroupActiveProposalItemReply = 65896,
|
|
GroupVoteHistoryRequest = 65897,
|
|
GroupVoteHistoryItemReply = 65898,
|
|
StartGroupProposal = 65899,
|
|
GroupProposalBallot = 65900,
|
|
GroupMembersRequest = 65902,
|
|
GroupMembersReply = 65903,
|
|
ActivateGroup = 65904,
|
|
SetGroupContribution = 65905,
|
|
SetGroupAcceptNotices = 65906,
|
|
GroupRoleDataRequest = 65907,
|
|
GroupRoleDataReply = 65908,
|
|
GroupRoleMembersRequest = 65909,
|
|
GroupRoleMembersReply = 65910,
|
|
GroupTitlesRequest = 65911,
|
|
GroupTitlesReply = 65912,
|
|
GroupTitleUpdate = 65913,
|
|
GroupRoleUpdate = 65914,
|
|
LiveHelpGroupRequest = 65915,
|
|
LiveHelpGroupReply = 65916,
|
|
AgentWearablesRequest = 65917,
|
|
AgentWearablesUpdate = 65918,
|
|
AgentIsNowWearing = 65919,
|
|
AgentCachedTexture = 65920,
|
|
AgentCachedTextureResponse = 65921,
|
|
AgentDataUpdateRequest = 65922,
|
|
AgentDataUpdate = 65923,
|
|
GroupDataUpdate = 65924,
|
|
AgentGroupDataUpdate = 65925,
|
|
AgentDropGroup = 65926,
|
|
RezSingleAttachmentFromInv = 65931,
|
|
RezMultipleAttachmentsFromInv = 65932,
|
|
DetachAttachmentIntoInv = 65933,
|
|
CreateNewOutfitAttachments = 65934,
|
|
UserInfoRequest = 65935,
|
|
UserInfoReply = 65936,
|
|
UpdateUserInfo = 65937,
|
|
InitiateDownload = 65939,
|
|
MapLayerRequest = 65941,
|
|
MapLayerReply = 65942,
|
|
MapBlockRequest = 65943,
|
|
MapNameRequest = 65944,
|
|
MapBlockReply = 65945,
|
|
MapItemRequest = 65946,
|
|
MapItemReply = 65947,
|
|
SendPostcard = 65948,
|
|
ParcelMediaCommandMessage = 65955,
|
|
ParcelMediaUpdate = 65956,
|
|
LandStatRequest = 65957,
|
|
LandStatReply = 65958,
|
|
Error = 65959,
|
|
ObjectIncludeInSearch = 65960,
|
|
RezRestoreToWorld = 65961,
|
|
LinkInventoryItem = 65962,
|
|
RetrieveIMsExtended = 65963,
|
|
JoinGroupRequestExtended = 65964,
|
|
CreateGroupRequestExtended = 65965,
|
|
LargeGenericMessage = 65966,
|
|
PacketAck = 131067,
|
|
OpenCircuit = 131068,
|
|
CloseCircuit = 131069,
|
|
ObjectAdd = 131073,
|
|
MultipleObjectUpdate = 131074,
|
|
RequestMultipleObjects = 131075,
|
|
ObjectPosition = 131076,
|
|
RequestObjectPropertiesFamily = 131077,
|
|
CoarseLocationUpdate = 131078,
|
|
CrossedRegion = 131079,
|
|
ConfirmEnableSimulator = 131080,
|
|
ObjectProperties = 131081,
|
|
ObjectPropertiesFamily = 131082,
|
|
ParcelPropertiesRequest = 131083,
|
|
AttachedSound = 131085,
|
|
AttachedSoundGainChange = 131086,
|
|
PreloadSound = 131087,
|
|
ViewerEffect = 131089,
|
|
StartPingCheck = 196609,
|
|
CompletePingCheck = 196610,
|
|
AgentUpdate = 196612,
|
|
AgentAnimation = 196613,
|
|
AgentRequestSit = 196614,
|
|
AgentSit = 196615,
|
|
RequestImage = 196616,
|
|
ImageData = 196617,
|
|
ImagePacket = 196618,
|
|
LayerData = 196619,
|
|
ObjectUpdate = 196620,
|
|
ObjectUpdateCompressed = 196621,
|
|
ObjectUpdateCached = 196622,
|
|
ImprovedTerseObjectUpdate = 196623,
|
|
KillObject = 196624,
|
|
TransferPacket = 196625,
|
|
SendXferPacket = 196626,
|
|
ConfirmXferPacket = 196627,
|
|
AvatarAnimation = 196628,
|
|
AvatarSitResponse = 196629,
|
|
CameraConstraint = 196630,
|
|
ParcelProperties = 196631,
|
|
ChildAgentUpdate = 196633,
|
|
ChildAgentAlive = 196634,
|
|
ChildAgentPositionUpdate = 196635,
|
|
SoundTrigger = 196637,
|
|
ObjectAnimation = 196638,
|
|
GenericStreamingMessage = 196639,
|
|
}
|
|
|
|
public abstract partial class Packet
|
|
{
|
|
public const int MTU = 1200;
|
|
|
|
public Header Header;
|
|
public bool HasVariableBlocks;
|
|
public PacketType Type;
|
|
public abstract int Length { get; }
|
|
public abstract void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer);
|
|
public abstract void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd);
|
|
public abstract byte[] ToBytes();
|
|
public abstract byte[][] ToBytesMultiple();
|
|
|
|
public virtual byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public virtual byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public virtual bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static PacketType GetType(ushort id, PacketFrequency frequency)
|
|
{
|
|
switch (frequency)
|
|
{
|
|
case PacketFrequency.Low:
|
|
switch (id)
|
|
{
|
|
case 1: return PacketType.TestMessage;
|
|
case 3: return PacketType.UseCircuitCode;
|
|
case 10: return PacketType.TelehubInfo;
|
|
case 24: return PacketType.EconomyDataRequest;
|
|
case 25: return PacketType.EconomyData;
|
|
case 26: return PacketType.AvatarPickerRequest;
|
|
case 28: return PacketType.AvatarPickerReply;
|
|
case 29: return PacketType.PlacesQuery;
|
|
case 30: return PacketType.PlacesReply;
|
|
case 31: return PacketType.DirFindQuery;
|
|
case 33: return PacketType.DirPlacesQuery;
|
|
case 35: return PacketType.DirPlacesReply;
|
|
case 36: return PacketType.DirPeopleReply;
|
|
case 37: return PacketType.DirEventsReply;
|
|
case 38: return PacketType.DirGroupsReply;
|
|
case 39: return PacketType.DirClassifiedQuery;
|
|
case 41: return PacketType.DirClassifiedReply;
|
|
case 42: return PacketType.AvatarClassifiedReply;
|
|
case 43: return PacketType.ClassifiedInfoRequest;
|
|
case 44: return PacketType.ClassifiedInfoReply;
|
|
case 45: return PacketType.ClassifiedInfoUpdate;
|
|
case 46: return PacketType.ClassifiedDelete;
|
|
case 47: return PacketType.ClassifiedGodDelete;
|
|
case 48: return PacketType.DirLandQuery;
|
|
case 50: return PacketType.DirLandReply;
|
|
case 51: return PacketType.DirPopularQuery;
|
|
case 53: return PacketType.DirPopularReply;
|
|
case 54: return PacketType.ParcelInfoRequest;
|
|
case 55: return PacketType.ParcelInfoReply;
|
|
case 56: return PacketType.ParcelObjectOwnersRequest;
|
|
case 57: return PacketType.ParcelObjectOwnersReply;
|
|
case 58: return PacketType.GroupNoticesListRequest;
|
|
case 59: return PacketType.GroupNoticesListReply;
|
|
case 60: return PacketType.GroupNoticeRequest;
|
|
case 62: return PacketType.TeleportRequest;
|
|
case 63: return PacketType.TeleportLocationRequest;
|
|
case 64: return PacketType.TeleportLocal;
|
|
case 65: return PacketType.TeleportLandmarkRequest;
|
|
case 66: return PacketType.TeleportProgress;
|
|
case 69: return PacketType.TeleportFinish;
|
|
case 70: return PacketType.StartLure;
|
|
case 71: return PacketType.TeleportLureRequest;
|
|
case 72: return PacketType.TeleportCancel;
|
|
case 73: return PacketType.TeleportStart;
|
|
case 74: return PacketType.TeleportFailed;
|
|
case 75: return PacketType.Undo;
|
|
case 76: return PacketType.Redo;
|
|
case 77: return PacketType.UndoLand;
|
|
case 78: return PacketType.AgentPause;
|
|
case 79: return PacketType.AgentResume;
|
|
case 80: return PacketType.ChatFromViewer;
|
|
case 81: return PacketType.AgentThrottle;
|
|
case 82: return PacketType.AgentFOV;
|
|
case 83: return PacketType.AgentHeightWidth;
|
|
case 84: return PacketType.AgentSetAppearance;
|
|
case 85: return PacketType.AgentQuitCopy;
|
|
case 86: return PacketType.ImageNotInDatabase;
|
|
case 87: return PacketType.RebakeAvatarTextures;
|
|
case 88: return PacketType.SetAlwaysRun;
|
|
case 89: return PacketType.ObjectDelete;
|
|
case 90: return PacketType.ObjectDuplicate;
|
|
case 91: return PacketType.ObjectDuplicateOnRay;
|
|
case 92: return PacketType.ObjectScale;
|
|
case 93: return PacketType.ObjectRotation;
|
|
case 94: return PacketType.ObjectFlagUpdate;
|
|
case 95: return PacketType.ObjectClickAction;
|
|
case 96: return PacketType.ObjectImage;
|
|
case 97: return PacketType.ObjectMaterial;
|
|
case 98: return PacketType.ObjectShape;
|
|
case 99: return PacketType.ObjectExtraParams;
|
|
case 100: return PacketType.ObjectOwner;
|
|
case 101: return PacketType.ObjectGroup;
|
|
case 102: return PacketType.ObjectBuy;
|
|
case 103: return PacketType.BuyObjectInventory;
|
|
case 104: return PacketType.DerezContainer;
|
|
case 105: return PacketType.ObjectPermissions;
|
|
case 106: return PacketType.ObjectSaleInfo;
|
|
case 107: return PacketType.ObjectName;
|
|
case 108: return PacketType.ObjectDescription;
|
|
case 109: return PacketType.ObjectCategory;
|
|
case 110: return PacketType.ObjectSelect;
|
|
case 111: return PacketType.ObjectDeselect;
|
|
case 112: return PacketType.ObjectAttach;
|
|
case 113: return PacketType.ObjectDetach;
|
|
case 114: return PacketType.ObjectDrop;
|
|
case 115: return PacketType.ObjectLink;
|
|
case 116: return PacketType.ObjectDelink;
|
|
case 117: return PacketType.ObjectGrab;
|
|
case 118: return PacketType.ObjectGrabUpdate;
|
|
case 119: return PacketType.ObjectDeGrab;
|
|
case 120: return PacketType.ObjectSpinStart;
|
|
case 121: return PacketType.ObjectSpinUpdate;
|
|
case 122: return PacketType.ObjectSpinStop;
|
|
case 123: return PacketType.ObjectExportSelected;
|
|
case 124: return PacketType.ModifyLand;
|
|
case 125: return PacketType.VelocityInterpolateOn;
|
|
case 126: return PacketType.VelocityInterpolateOff;
|
|
case 127: return PacketType.StateSave;
|
|
case 128: return PacketType.ReportAutosaveCrash;
|
|
case 129: return PacketType.SimWideDeletes;
|
|
case 130: return PacketType.TrackAgent;
|
|
case 131: return PacketType.ViewerStats;
|
|
case 132: return PacketType.ScriptAnswerYes;
|
|
case 133: return PacketType.UserReport;
|
|
case 134: return PacketType.AlertMessage;
|
|
case 135: return PacketType.AgentAlertMessage;
|
|
case 136: return PacketType.MeanCollisionAlert;
|
|
case 137: return PacketType.ViewerFrozenMessage;
|
|
case 138: return PacketType.HealthMessage;
|
|
case 139: return PacketType.ChatFromSimulator;
|
|
case 140: return PacketType.SimStats;
|
|
case 141: return PacketType.RequestRegionInfo;
|
|
case 142: return PacketType.RegionInfo;
|
|
case 143: return PacketType.GodUpdateRegionInfo;
|
|
case 148: return PacketType.RegionHandshake;
|
|
case 149: return PacketType.RegionHandshakeReply;
|
|
case 150: return PacketType.SimulatorViewerTimeMessage;
|
|
case 151: return PacketType.EnableSimulator;
|
|
case 152: return PacketType.DisableSimulator;
|
|
case 153: return PacketType.TransferRequest;
|
|
case 154: return PacketType.TransferInfo;
|
|
case 155: return PacketType.TransferAbort;
|
|
case 156: return PacketType.RequestXfer;
|
|
case 157: return PacketType.AbortXfer;
|
|
case 158: return PacketType.AvatarAppearance;
|
|
case 159: return PacketType.SetFollowCamProperties;
|
|
case 160: return PacketType.ClearFollowCamProperties;
|
|
case 161: return PacketType.RequestPayPrice;
|
|
case 162: return PacketType.PayPriceReply;
|
|
case 163: return PacketType.KickUser;
|
|
case 165: return PacketType.GodKickUser;
|
|
case 167: return PacketType.EjectUser;
|
|
case 168: return PacketType.FreezeUser;
|
|
case 169: return PacketType.AvatarPropertiesRequest;
|
|
case 171: return PacketType.AvatarPropertiesReply;
|
|
case 172: return PacketType.AvatarInterestsReply;
|
|
case 173: return PacketType.AvatarGroupsReply;
|
|
case 174: return PacketType.AvatarPropertiesUpdate;
|
|
case 175: return PacketType.AvatarInterestsUpdate;
|
|
case 176: return PacketType.AvatarNotesReply;
|
|
case 177: return PacketType.AvatarNotesUpdate;
|
|
case 178: return PacketType.AvatarPicksReply;
|
|
case 179: return PacketType.EventInfoRequest;
|
|
case 180: return PacketType.EventInfoReply;
|
|
case 181: return PacketType.EventNotificationAddRequest;
|
|
case 182: return PacketType.EventNotificationRemoveRequest;
|
|
case 183: return PacketType.EventGodDelete;
|
|
case 184: return PacketType.PickInfoReply;
|
|
case 185: return PacketType.PickInfoUpdate;
|
|
case 186: return PacketType.PickDelete;
|
|
case 187: return PacketType.PickGodDelete;
|
|
case 188: return PacketType.ScriptQuestion;
|
|
case 189: return PacketType.ScriptControlChange;
|
|
case 190: return PacketType.ScriptDialog;
|
|
case 191: return PacketType.ScriptDialogReply;
|
|
case 192: return PacketType.ForceScriptControlRelease;
|
|
case 193: return PacketType.RevokePermissions;
|
|
case 194: return PacketType.LoadURL;
|
|
case 195: return PacketType.ScriptTeleportRequest;
|
|
case 196: return PacketType.ParcelOverlay;
|
|
case 197: return PacketType.ParcelPropertiesRequestByID;
|
|
case 198: return PacketType.ParcelPropertiesUpdate;
|
|
case 199: return PacketType.ParcelReturnObjects;
|
|
case 200: return PacketType.ParcelSetOtherCleanTime;
|
|
case 201: return PacketType.ParcelDisableObjects;
|
|
case 202: return PacketType.ParcelSelectObjects;
|
|
case 203: return PacketType.EstateCovenantRequest;
|
|
case 204: return PacketType.EstateCovenantReply;
|
|
case 205: return PacketType.ForceObjectSelect;
|
|
case 206: return PacketType.ParcelBuyPass;
|
|
case 207: return PacketType.ParcelDeedToGroup;
|
|
case 208: return PacketType.ParcelReclaim;
|
|
case 209: return PacketType.ParcelClaim;
|
|
case 210: return PacketType.ParcelJoin;
|
|
case 211: return PacketType.ParcelDivide;
|
|
case 212: return PacketType.ParcelRelease;
|
|
case 213: return PacketType.ParcelBuy;
|
|
case 214: return PacketType.ParcelGodForceOwner;
|
|
case 215: return PacketType.ParcelAccessListRequest;
|
|
case 216: return PacketType.ParcelAccessListReply;
|
|
case 217: return PacketType.ParcelAccessListUpdate;
|
|
case 218: return PacketType.ParcelDwellRequest;
|
|
case 219: return PacketType.ParcelDwellReply;
|
|
case 227: return PacketType.ParcelGodMarkAsContent;
|
|
case 228: return PacketType.ViewerStartAuction;
|
|
case 235: return PacketType.UUIDNameRequest;
|
|
case 236: return PacketType.UUIDNameReply;
|
|
case 237: return PacketType.UUIDGroupNameRequest;
|
|
case 238: return PacketType.UUIDGroupNameReply;
|
|
case 240: return PacketType.ChildAgentDying;
|
|
case 241: return PacketType.ChildAgentUnknown;
|
|
case 243: return PacketType.GetScriptRunning;
|
|
case 244: return PacketType.ScriptRunningReply;
|
|
case 245: return PacketType.SetScriptRunning;
|
|
case 246: return PacketType.ScriptReset;
|
|
case 247: return PacketType.ScriptSensorRequest;
|
|
case 248: return PacketType.ScriptSensorReply;
|
|
case 249: return PacketType.CompleteAgentMovement;
|
|
case 250: return PacketType.AgentMovementComplete;
|
|
case 252: return PacketType.LogoutRequest;
|
|
case 253: return PacketType.LogoutReply;
|
|
case 254: return PacketType.ImprovedInstantMessage;
|
|
case 255: return PacketType.RetrieveInstantMessages;
|
|
case 256: return PacketType.FindAgent;
|
|
case 257: return PacketType.RequestGodlikePowers;
|
|
case 258: return PacketType.GrantGodlikePowers;
|
|
case 259: return PacketType.GodlikeMessage;
|
|
case 260: return PacketType.EstateOwnerMessage;
|
|
case 261: return PacketType.GenericMessage;
|
|
case 262: return PacketType.MuteListRequest;
|
|
case 263: return PacketType.UpdateMuteListEntry;
|
|
case 264: return PacketType.RemoveMuteListEntry;
|
|
case 265: return PacketType.CopyInventoryFromNotecard;
|
|
case 266: return PacketType.UpdateInventoryItem;
|
|
case 267: return PacketType.UpdateCreateInventoryItem;
|
|
case 268: return PacketType.MoveInventoryItem;
|
|
case 269: return PacketType.CopyInventoryItem;
|
|
case 270: return PacketType.RemoveInventoryItem;
|
|
case 271: return PacketType.ChangeInventoryItemFlags;
|
|
case 272: return PacketType.SaveAssetIntoInventory;
|
|
case 273: return PacketType.CreateInventoryFolder;
|
|
case 274: return PacketType.UpdateInventoryFolder;
|
|
case 275: return PacketType.MoveInventoryFolder;
|
|
case 276: return PacketType.RemoveInventoryFolder;
|
|
case 277: return PacketType.FetchInventoryDescendents;
|
|
case 278: return PacketType.InventoryDescendents;
|
|
case 279: return PacketType.FetchInventory;
|
|
case 280: return PacketType.FetchInventoryReply;
|
|
case 281: return PacketType.BulkUpdateInventory;
|
|
case 284: return PacketType.RemoveInventoryObjects;
|
|
case 285: return PacketType.PurgeInventoryDescendents;
|
|
case 286: return PacketType.UpdateTaskInventory;
|
|
case 287: return PacketType.RemoveTaskInventory;
|
|
case 288: return PacketType.MoveTaskInventory;
|
|
case 289: return PacketType.RequestTaskInventory;
|
|
case 290: return PacketType.ReplyTaskInventory;
|
|
case 291: return PacketType.DeRezObject;
|
|
case 292: return PacketType.DeRezAck;
|
|
case 293: return PacketType.RezObject;
|
|
case 294: return PacketType.RezObjectFromNotecard;
|
|
case 297: return PacketType.AcceptFriendship;
|
|
case 298: return PacketType.DeclineFriendship;
|
|
case 300: return PacketType.TerminateFriendship;
|
|
case 301: return PacketType.OfferCallingCard;
|
|
case 302: return PacketType.AcceptCallingCard;
|
|
case 303: return PacketType.DeclineCallingCard;
|
|
case 304: return PacketType.RezScript;
|
|
case 305: return PacketType.CreateInventoryItem;
|
|
case 306: return PacketType.CreateLandmarkForEvent;
|
|
case 309: return PacketType.RegionHandleRequest;
|
|
case 310: return PacketType.RegionIDAndHandleReply;
|
|
case 311: return PacketType.MoneyTransferRequest;
|
|
case 313: return PacketType.MoneyBalanceRequest;
|
|
case 314: return PacketType.MoneyBalanceReply;
|
|
case 315: return PacketType.RoutedMoneyBalanceReply;
|
|
case 316: return PacketType.ActivateGestures;
|
|
case 317: return PacketType.DeactivateGestures;
|
|
case 318: return PacketType.MuteListUpdate;
|
|
case 319: return PacketType.UseCachedMuteList;
|
|
case 320: return PacketType.GrantUserRights;
|
|
case 321: return PacketType.ChangeUserRights;
|
|
case 322: return PacketType.OnlineNotification;
|
|
case 323: return PacketType.OfflineNotification;
|
|
case 324: return PacketType.SetStartLocationRequest;
|
|
case 333: return PacketType.AssetUploadRequest;
|
|
case 334: return PacketType.AssetUploadComplete;
|
|
case 339: return PacketType.CreateGroupRequest;
|
|
case 340: return PacketType.CreateGroupReply;
|
|
case 341: return PacketType.UpdateGroupInfo;
|
|
case 342: return PacketType.GroupRoleChanges;
|
|
case 343: return PacketType.JoinGroupRequest;
|
|
case 344: return PacketType.JoinGroupReply;
|
|
case 345: return PacketType.EjectGroupMemberRequest;
|
|
case 346: return PacketType.EjectGroupMemberReply;
|
|
case 347: return PacketType.LeaveGroupRequest;
|
|
case 348: return PacketType.LeaveGroupReply;
|
|
case 349: return PacketType.InviteGroupRequest;
|
|
case 351: return PacketType.GroupProfileRequest;
|
|
case 352: return PacketType.GroupProfileReply;
|
|
case 353: return PacketType.GroupAccountSummaryRequest;
|
|
case 354: return PacketType.GroupAccountSummaryReply;
|
|
case 355: return PacketType.GroupAccountDetailsRequest;
|
|
case 356: return PacketType.GroupAccountDetailsReply;
|
|
case 357: return PacketType.GroupAccountTransactionsRequest;
|
|
case 358: return PacketType.GroupAccountTransactionsReply;
|
|
case 359: return PacketType.GroupActiveProposalsRequest;
|
|
case 360: return PacketType.GroupActiveProposalItemReply;
|
|
case 361: return PacketType.GroupVoteHistoryRequest;
|
|
case 362: return PacketType.GroupVoteHistoryItemReply;
|
|
case 363: return PacketType.StartGroupProposal;
|
|
case 364: return PacketType.GroupProposalBallot;
|
|
case 366: return PacketType.GroupMembersRequest;
|
|
case 367: return PacketType.GroupMembersReply;
|
|
case 368: return PacketType.ActivateGroup;
|
|
case 369: return PacketType.SetGroupContribution;
|
|
case 370: return PacketType.SetGroupAcceptNotices;
|
|
case 371: return PacketType.GroupRoleDataRequest;
|
|
case 372: return PacketType.GroupRoleDataReply;
|
|
case 373: return PacketType.GroupRoleMembersRequest;
|
|
case 374: return PacketType.GroupRoleMembersReply;
|
|
case 375: return PacketType.GroupTitlesRequest;
|
|
case 376: return PacketType.GroupTitlesReply;
|
|
case 377: return PacketType.GroupTitleUpdate;
|
|
case 378: return PacketType.GroupRoleUpdate;
|
|
case 379: return PacketType.LiveHelpGroupRequest;
|
|
case 380: return PacketType.LiveHelpGroupReply;
|
|
case 381: return PacketType.AgentWearablesRequest;
|
|
case 382: return PacketType.AgentWearablesUpdate;
|
|
case 383: return PacketType.AgentIsNowWearing;
|
|
case 384: return PacketType.AgentCachedTexture;
|
|
case 385: return PacketType.AgentCachedTextureResponse;
|
|
case 386: return PacketType.AgentDataUpdateRequest;
|
|
case 387: return PacketType.AgentDataUpdate;
|
|
case 388: return PacketType.GroupDataUpdate;
|
|
case 389: return PacketType.AgentGroupDataUpdate;
|
|
case 390: return PacketType.AgentDropGroup;
|
|
case 395: return PacketType.RezSingleAttachmentFromInv;
|
|
case 396: return PacketType.RezMultipleAttachmentsFromInv;
|
|
case 397: return PacketType.DetachAttachmentIntoInv;
|
|
case 398: return PacketType.CreateNewOutfitAttachments;
|
|
case 399: return PacketType.UserInfoRequest;
|
|
case 400: return PacketType.UserInfoReply;
|
|
case 401: return PacketType.UpdateUserInfo;
|
|
case 403: return PacketType.InitiateDownload;
|
|
case 405: return PacketType.MapLayerRequest;
|
|
case 406: return PacketType.MapLayerReply;
|
|
case 407: return PacketType.MapBlockRequest;
|
|
case 408: return PacketType.MapNameRequest;
|
|
case 409: return PacketType.MapBlockReply;
|
|
case 410: return PacketType.MapItemRequest;
|
|
case 411: return PacketType.MapItemReply;
|
|
case 412: return PacketType.SendPostcard;
|
|
case 419: return PacketType.ParcelMediaCommandMessage;
|
|
case 420: return PacketType.ParcelMediaUpdate;
|
|
case 421: return PacketType.LandStatRequest;
|
|
case 422: return PacketType.LandStatReply;
|
|
case 423: return PacketType.Error;
|
|
case 424: return PacketType.ObjectIncludeInSearch;
|
|
case 425: return PacketType.RezRestoreToWorld;
|
|
case 426: return PacketType.LinkInventoryItem;
|
|
case 427: return PacketType.RetrieveIMsExtended;
|
|
case 428: return PacketType.JoinGroupRequestExtended;
|
|
case 429: return PacketType.CreateGroupRequestExtended;
|
|
case 430: return PacketType.LargeGenericMessage;
|
|
case 65531: return PacketType.PacketAck;
|
|
case 65532: return PacketType.OpenCircuit;
|
|
case 65533: return PacketType.CloseCircuit;
|
|
}
|
|
break;
|
|
case PacketFrequency.Medium:
|
|
switch (id)
|
|
{
|
|
case 1: return PacketType.ObjectAdd;
|
|
case 2: return PacketType.MultipleObjectUpdate;
|
|
case 3: return PacketType.RequestMultipleObjects;
|
|
case 4: return PacketType.ObjectPosition;
|
|
case 5: return PacketType.RequestObjectPropertiesFamily;
|
|
case 6: return PacketType.CoarseLocationUpdate;
|
|
case 7: return PacketType.CrossedRegion;
|
|
case 8: return PacketType.ConfirmEnableSimulator;
|
|
case 9: return PacketType.ObjectProperties;
|
|
case 10: return PacketType.ObjectPropertiesFamily;
|
|
case 11: return PacketType.ParcelPropertiesRequest;
|
|
case 13: return PacketType.AttachedSound;
|
|
case 14: return PacketType.AttachedSoundGainChange;
|
|
case 15: return PacketType.PreloadSound;
|
|
case 17: return PacketType.ViewerEffect;
|
|
}
|
|
break;
|
|
case PacketFrequency.High:
|
|
switch (id)
|
|
{
|
|
case 1: return PacketType.StartPingCheck;
|
|
case 2: return PacketType.CompletePingCheck;
|
|
case 4: return PacketType.AgentUpdate;
|
|
case 5: return PacketType.AgentAnimation;
|
|
case 6: return PacketType.AgentRequestSit;
|
|
case 7: return PacketType.AgentSit;
|
|
case 8: return PacketType.RequestImage;
|
|
case 9: return PacketType.ImageData;
|
|
case 10: return PacketType.ImagePacket;
|
|
case 11: return PacketType.LayerData;
|
|
case 12: return PacketType.ObjectUpdate;
|
|
case 13: return PacketType.ObjectUpdateCompressed;
|
|
case 14: return PacketType.ObjectUpdateCached;
|
|
case 15: return PacketType.ImprovedTerseObjectUpdate;
|
|
case 16: return PacketType.KillObject;
|
|
case 17: return PacketType.TransferPacket;
|
|
case 18: return PacketType.SendXferPacket;
|
|
case 19: return PacketType.ConfirmXferPacket;
|
|
case 20: return PacketType.AvatarAnimation;
|
|
case 21: return PacketType.AvatarSitResponse;
|
|
case 22: return PacketType.CameraConstraint;
|
|
case 23: return PacketType.ParcelProperties;
|
|
case 25: return PacketType.ChildAgentUpdate;
|
|
case 26: return PacketType.ChildAgentAlive;
|
|
case 27: return PacketType.ChildAgentPositionUpdate;
|
|
case 29: return PacketType.SoundTrigger;
|
|
case 30: return PacketType.ObjectAnimation;
|
|
case 31: return PacketType.GenericStreamingMessage;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return PacketType.Default;
|
|
}
|
|
|
|
public static Packet BuildPacket(PacketType type)
|
|
{
|
|
if(type == PacketType.StartPingCheck) return new StartPingCheckPacket();
|
|
if(type == PacketType.CompletePingCheck) return new CompletePingCheckPacket();
|
|
if(type == PacketType.AgentUpdate) return new AgentUpdatePacket();
|
|
if(type == PacketType.AgentAnimation) return new AgentAnimationPacket();
|
|
if(type == PacketType.AgentRequestSit) return new AgentRequestSitPacket();
|
|
if(type == PacketType.AgentSit) return new AgentSitPacket();
|
|
if(type == PacketType.RequestImage) return new RequestImagePacket();
|
|
if(type == PacketType.ImageData) return new ImageDataPacket();
|
|
if(type == PacketType.ImagePacket) return new ImagePacketPacket();
|
|
if(type == PacketType.LayerData) return new LayerDataPacket();
|
|
if(type == PacketType.ObjectUpdate) return new ObjectUpdatePacket();
|
|
if(type == PacketType.ObjectUpdateCompressed) return new ObjectUpdateCompressedPacket();
|
|
if(type == PacketType.ObjectUpdateCached) return new ObjectUpdateCachedPacket();
|
|
if(type == PacketType.ImprovedTerseObjectUpdate) return new ImprovedTerseObjectUpdatePacket();
|
|
if(type == PacketType.KillObject) return new KillObjectPacket();
|
|
if(type == PacketType.TransferPacket) return new TransferPacketPacket();
|
|
if(type == PacketType.SendXferPacket) return new SendXferPacketPacket();
|
|
if(type == PacketType.ConfirmXferPacket) return new ConfirmXferPacketPacket();
|
|
if(type == PacketType.AvatarAnimation) return new AvatarAnimationPacket();
|
|
if(type == PacketType.AvatarSitResponse) return new AvatarSitResponsePacket();
|
|
if(type == PacketType.CameraConstraint) return new CameraConstraintPacket();
|
|
if(type == PacketType.ParcelProperties) return new ParcelPropertiesPacket();
|
|
if(type == PacketType.ChildAgentUpdate) return new ChildAgentUpdatePacket();
|
|
if(type == PacketType.ChildAgentAlive) return new ChildAgentAlivePacket();
|
|
if(type == PacketType.ChildAgentPositionUpdate) return new ChildAgentPositionUpdatePacket();
|
|
if(type == PacketType.SoundTrigger) return new SoundTriggerPacket();
|
|
if(type == PacketType.ObjectAnimation) return new ObjectAnimationPacket();
|
|
if(type == PacketType.GenericStreamingMessage) return new GenericStreamingMessagePacket();
|
|
if(type == PacketType.ObjectAdd) return new ObjectAddPacket();
|
|
if(type == PacketType.MultipleObjectUpdate) return new MultipleObjectUpdatePacket();
|
|
if(type == PacketType.RequestMultipleObjects) return new RequestMultipleObjectsPacket();
|
|
if(type == PacketType.ObjectPosition) return new ObjectPositionPacket();
|
|
if(type == PacketType.RequestObjectPropertiesFamily) return new RequestObjectPropertiesFamilyPacket();
|
|
if(type == PacketType.CoarseLocationUpdate) return new CoarseLocationUpdatePacket();
|
|
if(type == PacketType.CrossedRegion) return new CrossedRegionPacket();
|
|
if(type == PacketType.ConfirmEnableSimulator) return new ConfirmEnableSimulatorPacket();
|
|
if(type == PacketType.ObjectProperties) return new ObjectPropertiesPacket();
|
|
if(type == PacketType.ObjectPropertiesFamily) return new ObjectPropertiesFamilyPacket();
|
|
if(type == PacketType.ParcelPropertiesRequest) return new ParcelPropertiesRequestPacket();
|
|
if(type == PacketType.AttachedSound) return new AttachedSoundPacket();
|
|
if(type == PacketType.AttachedSoundGainChange) return new AttachedSoundGainChangePacket();
|
|
if(type == PacketType.PreloadSound) return new PreloadSoundPacket();
|
|
if(type == PacketType.ViewerEffect) return new ViewerEffectPacket();
|
|
if(type == PacketType.TestMessage) return new TestMessagePacket();
|
|
if(type == PacketType.UseCircuitCode) return new UseCircuitCodePacket();
|
|
if(type == PacketType.TelehubInfo) return new TelehubInfoPacket();
|
|
if(type == PacketType.EconomyDataRequest) return new EconomyDataRequestPacket();
|
|
if(type == PacketType.EconomyData) return new EconomyDataPacket();
|
|
if(type == PacketType.AvatarPickerRequest) return new AvatarPickerRequestPacket();
|
|
if(type == PacketType.AvatarPickerReply) return new AvatarPickerReplyPacket();
|
|
if(type == PacketType.PlacesQuery) return new PlacesQueryPacket();
|
|
if(type == PacketType.PlacesReply) return new PlacesReplyPacket();
|
|
if(type == PacketType.DirFindQuery) return new DirFindQueryPacket();
|
|
if(type == PacketType.DirPlacesQuery) return new DirPlacesQueryPacket();
|
|
if(type == PacketType.DirPlacesReply) return new DirPlacesReplyPacket();
|
|
if(type == PacketType.DirPeopleReply) return new DirPeopleReplyPacket();
|
|
if(type == PacketType.DirEventsReply) return new DirEventsReplyPacket();
|
|
if(type == PacketType.DirGroupsReply) return new DirGroupsReplyPacket();
|
|
if(type == PacketType.DirClassifiedQuery) return new DirClassifiedQueryPacket();
|
|
if(type == PacketType.DirClassifiedReply) return new DirClassifiedReplyPacket();
|
|
if(type == PacketType.AvatarClassifiedReply) return new AvatarClassifiedReplyPacket();
|
|
if(type == PacketType.ClassifiedInfoRequest) return new ClassifiedInfoRequestPacket();
|
|
if(type == PacketType.ClassifiedInfoReply) return new ClassifiedInfoReplyPacket();
|
|
if(type == PacketType.ClassifiedInfoUpdate) return new ClassifiedInfoUpdatePacket();
|
|
if(type == PacketType.ClassifiedDelete) return new ClassifiedDeletePacket();
|
|
if(type == PacketType.ClassifiedGodDelete) return new ClassifiedGodDeletePacket();
|
|
if(type == PacketType.DirLandQuery) return new DirLandQueryPacket();
|
|
if(type == PacketType.DirLandReply) return new DirLandReplyPacket();
|
|
if(type == PacketType.DirPopularQuery) return new DirPopularQueryPacket();
|
|
if(type == PacketType.DirPopularReply) return new DirPopularReplyPacket();
|
|
if(type == PacketType.ParcelInfoRequest) return new ParcelInfoRequestPacket();
|
|
if(type == PacketType.ParcelInfoReply) return new ParcelInfoReplyPacket();
|
|
if(type == PacketType.ParcelObjectOwnersRequest) return new ParcelObjectOwnersRequestPacket();
|
|
if(type == PacketType.ParcelObjectOwnersReply) return new ParcelObjectOwnersReplyPacket();
|
|
if(type == PacketType.GroupNoticesListRequest) return new GroupNoticesListRequestPacket();
|
|
if(type == PacketType.GroupNoticesListReply) return new GroupNoticesListReplyPacket();
|
|
if(type == PacketType.GroupNoticeRequest) return new GroupNoticeRequestPacket();
|
|
if(type == PacketType.TeleportRequest) return new TeleportRequestPacket();
|
|
if(type == PacketType.TeleportLocationRequest) return new TeleportLocationRequestPacket();
|
|
if(type == PacketType.TeleportLocal) return new TeleportLocalPacket();
|
|
if(type == PacketType.TeleportLandmarkRequest) return new TeleportLandmarkRequestPacket();
|
|
if(type == PacketType.TeleportProgress) return new TeleportProgressPacket();
|
|
if(type == PacketType.TeleportFinish) return new TeleportFinishPacket();
|
|
if(type == PacketType.StartLure) return new StartLurePacket();
|
|
if(type == PacketType.TeleportLureRequest) return new TeleportLureRequestPacket();
|
|
if(type == PacketType.TeleportCancel) return new TeleportCancelPacket();
|
|
if(type == PacketType.TeleportStart) return new TeleportStartPacket();
|
|
if(type == PacketType.TeleportFailed) return new TeleportFailedPacket();
|
|
if(type == PacketType.Undo) return new UndoPacket();
|
|
if(type == PacketType.Redo) return new RedoPacket();
|
|
if(type == PacketType.UndoLand) return new UndoLandPacket();
|
|
if(type == PacketType.AgentPause) return new AgentPausePacket();
|
|
if(type == PacketType.AgentResume) return new AgentResumePacket();
|
|
if(type == PacketType.ChatFromViewer) return new ChatFromViewerPacket();
|
|
if(type == PacketType.AgentThrottle) return new AgentThrottlePacket();
|
|
if(type == PacketType.AgentFOV) return new AgentFOVPacket();
|
|
if(type == PacketType.AgentHeightWidth) return new AgentHeightWidthPacket();
|
|
if(type == PacketType.AgentSetAppearance) return new AgentSetAppearancePacket();
|
|
if(type == PacketType.AgentQuitCopy) return new AgentQuitCopyPacket();
|
|
if(type == PacketType.ImageNotInDatabase) return new ImageNotInDatabasePacket();
|
|
if(type == PacketType.RebakeAvatarTextures) return new RebakeAvatarTexturesPacket();
|
|
if(type == PacketType.SetAlwaysRun) return new SetAlwaysRunPacket();
|
|
if(type == PacketType.ObjectDelete) return new ObjectDeletePacket();
|
|
if(type == PacketType.ObjectDuplicate) return new ObjectDuplicatePacket();
|
|
if(type == PacketType.ObjectDuplicateOnRay) return new ObjectDuplicateOnRayPacket();
|
|
if(type == PacketType.ObjectScale) return new ObjectScalePacket();
|
|
if(type == PacketType.ObjectRotation) return new ObjectRotationPacket();
|
|
if(type == PacketType.ObjectFlagUpdate) return new ObjectFlagUpdatePacket();
|
|
if(type == PacketType.ObjectClickAction) return new ObjectClickActionPacket();
|
|
if(type == PacketType.ObjectImage) return new ObjectImagePacket();
|
|
if(type == PacketType.ObjectMaterial) return new ObjectMaterialPacket();
|
|
if(type == PacketType.ObjectShape) return new ObjectShapePacket();
|
|
if(type == PacketType.ObjectExtraParams) return new ObjectExtraParamsPacket();
|
|
if(type == PacketType.ObjectOwner) return new ObjectOwnerPacket();
|
|
if(type == PacketType.ObjectGroup) return new ObjectGroupPacket();
|
|
if(type == PacketType.ObjectBuy) return new ObjectBuyPacket();
|
|
if(type == PacketType.BuyObjectInventory) return new BuyObjectInventoryPacket();
|
|
if(type == PacketType.DerezContainer) return new DerezContainerPacket();
|
|
if(type == PacketType.ObjectPermissions) return new ObjectPermissionsPacket();
|
|
if(type == PacketType.ObjectSaleInfo) return new ObjectSaleInfoPacket();
|
|
if(type == PacketType.ObjectName) return new ObjectNamePacket();
|
|
if(type == PacketType.ObjectDescription) return new ObjectDescriptionPacket();
|
|
if(type == PacketType.ObjectCategory) return new ObjectCategoryPacket();
|
|
if(type == PacketType.ObjectSelect) return new ObjectSelectPacket();
|
|
if(type == PacketType.ObjectDeselect) return new ObjectDeselectPacket();
|
|
if(type == PacketType.ObjectAttach) return new ObjectAttachPacket();
|
|
if(type == PacketType.ObjectDetach) return new ObjectDetachPacket();
|
|
if(type == PacketType.ObjectDrop) return new ObjectDropPacket();
|
|
if(type == PacketType.ObjectLink) return new ObjectLinkPacket();
|
|
if(type == PacketType.ObjectDelink) return new ObjectDelinkPacket();
|
|
if(type == PacketType.ObjectGrab) return new ObjectGrabPacket();
|
|
if(type == PacketType.ObjectGrabUpdate) return new ObjectGrabUpdatePacket();
|
|
if(type == PacketType.ObjectDeGrab) return new ObjectDeGrabPacket();
|
|
if(type == PacketType.ObjectSpinStart) return new ObjectSpinStartPacket();
|
|
if(type == PacketType.ObjectSpinUpdate) return new ObjectSpinUpdatePacket();
|
|
if(type == PacketType.ObjectSpinStop) return new ObjectSpinStopPacket();
|
|
if(type == PacketType.ObjectExportSelected) return new ObjectExportSelectedPacket();
|
|
if(type == PacketType.ModifyLand) return new ModifyLandPacket();
|
|
if(type == PacketType.VelocityInterpolateOn) return new VelocityInterpolateOnPacket();
|
|
if(type == PacketType.VelocityInterpolateOff) return new VelocityInterpolateOffPacket();
|
|
if(type == PacketType.StateSave) return new StateSavePacket();
|
|
if(type == PacketType.ReportAutosaveCrash) return new ReportAutosaveCrashPacket();
|
|
if(type == PacketType.SimWideDeletes) return new SimWideDeletesPacket();
|
|
if(type == PacketType.TrackAgent) return new TrackAgentPacket();
|
|
if(type == PacketType.ViewerStats) return new ViewerStatsPacket();
|
|
if(type == PacketType.ScriptAnswerYes) return new ScriptAnswerYesPacket();
|
|
if(type == PacketType.UserReport) return new UserReportPacket();
|
|
if(type == PacketType.AlertMessage) return new AlertMessagePacket();
|
|
if(type == PacketType.AgentAlertMessage) return new AgentAlertMessagePacket();
|
|
if(type == PacketType.MeanCollisionAlert) return new MeanCollisionAlertPacket();
|
|
if(type == PacketType.ViewerFrozenMessage) return new ViewerFrozenMessagePacket();
|
|
if(type == PacketType.HealthMessage) return new HealthMessagePacket();
|
|
if(type == PacketType.ChatFromSimulator) return new ChatFromSimulatorPacket();
|
|
if(type == PacketType.SimStats) return new SimStatsPacket();
|
|
if(type == PacketType.RequestRegionInfo) return new RequestRegionInfoPacket();
|
|
if(type == PacketType.RegionInfo) return new RegionInfoPacket();
|
|
if(type == PacketType.GodUpdateRegionInfo) return new GodUpdateRegionInfoPacket();
|
|
if(type == PacketType.RegionHandshake) return new RegionHandshakePacket();
|
|
if(type == PacketType.RegionHandshakeReply) return new RegionHandshakeReplyPacket();
|
|
if(type == PacketType.SimulatorViewerTimeMessage) return new SimulatorViewerTimeMessagePacket();
|
|
if(type == PacketType.EnableSimulator) return new EnableSimulatorPacket();
|
|
if(type == PacketType.DisableSimulator) return new DisableSimulatorPacket();
|
|
if(type == PacketType.TransferRequest) return new TransferRequestPacket();
|
|
if(type == PacketType.TransferInfo) return new TransferInfoPacket();
|
|
if(type == PacketType.TransferAbort) return new TransferAbortPacket();
|
|
if(type == PacketType.RequestXfer) return new RequestXferPacket();
|
|
if(type == PacketType.AbortXfer) return new AbortXferPacket();
|
|
if(type == PacketType.AvatarAppearance) return new AvatarAppearancePacket();
|
|
if(type == PacketType.SetFollowCamProperties) return new SetFollowCamPropertiesPacket();
|
|
if(type == PacketType.ClearFollowCamProperties) return new ClearFollowCamPropertiesPacket();
|
|
if(type == PacketType.RequestPayPrice) return new RequestPayPricePacket();
|
|
if(type == PacketType.PayPriceReply) return new PayPriceReplyPacket();
|
|
if(type == PacketType.KickUser) return new KickUserPacket();
|
|
if(type == PacketType.GodKickUser) return new GodKickUserPacket();
|
|
if(type == PacketType.EjectUser) return new EjectUserPacket();
|
|
if(type == PacketType.FreezeUser) return new FreezeUserPacket();
|
|
if(type == PacketType.AvatarPropertiesRequest) return new AvatarPropertiesRequestPacket();
|
|
if(type == PacketType.AvatarPropertiesReply) return new AvatarPropertiesReplyPacket();
|
|
if(type == PacketType.AvatarInterestsReply) return new AvatarInterestsReplyPacket();
|
|
if(type == PacketType.AvatarGroupsReply) return new AvatarGroupsReplyPacket();
|
|
if(type == PacketType.AvatarPropertiesUpdate) return new AvatarPropertiesUpdatePacket();
|
|
if(type == PacketType.AvatarInterestsUpdate) return new AvatarInterestsUpdatePacket();
|
|
if(type == PacketType.AvatarNotesReply) return new AvatarNotesReplyPacket();
|
|
if(type == PacketType.AvatarNotesUpdate) return new AvatarNotesUpdatePacket();
|
|
if(type == PacketType.AvatarPicksReply) return new AvatarPicksReplyPacket();
|
|
if(type == PacketType.EventInfoRequest) return new EventInfoRequestPacket();
|
|
if(type == PacketType.EventInfoReply) return new EventInfoReplyPacket();
|
|
if(type == PacketType.EventNotificationAddRequest) return new EventNotificationAddRequestPacket();
|
|
if(type == PacketType.EventNotificationRemoveRequest) return new EventNotificationRemoveRequestPacket();
|
|
if(type == PacketType.EventGodDelete) return new EventGodDeletePacket();
|
|
if(type == PacketType.PickInfoReply) return new PickInfoReplyPacket();
|
|
if(type == PacketType.PickInfoUpdate) return new PickInfoUpdatePacket();
|
|
if(type == PacketType.PickDelete) return new PickDeletePacket();
|
|
if(type == PacketType.PickGodDelete) return new PickGodDeletePacket();
|
|
if(type == PacketType.ScriptQuestion) return new ScriptQuestionPacket();
|
|
if(type == PacketType.ScriptControlChange) return new ScriptControlChangePacket();
|
|
if(type == PacketType.ScriptDialog) return new ScriptDialogPacket();
|
|
if(type == PacketType.ScriptDialogReply) return new ScriptDialogReplyPacket();
|
|
if(type == PacketType.ForceScriptControlRelease) return new ForceScriptControlReleasePacket();
|
|
if(type == PacketType.RevokePermissions) return new RevokePermissionsPacket();
|
|
if(type == PacketType.LoadURL) return new LoadURLPacket();
|
|
if(type == PacketType.ScriptTeleportRequest) return new ScriptTeleportRequestPacket();
|
|
if(type == PacketType.ParcelOverlay) return new ParcelOverlayPacket();
|
|
if(type == PacketType.ParcelPropertiesRequestByID) return new ParcelPropertiesRequestByIDPacket();
|
|
if(type == PacketType.ParcelPropertiesUpdate) return new ParcelPropertiesUpdatePacket();
|
|
if(type == PacketType.ParcelReturnObjects) return new ParcelReturnObjectsPacket();
|
|
if(type == PacketType.ParcelSetOtherCleanTime) return new ParcelSetOtherCleanTimePacket();
|
|
if(type == PacketType.ParcelDisableObjects) return new ParcelDisableObjectsPacket();
|
|
if(type == PacketType.ParcelSelectObjects) return new ParcelSelectObjectsPacket();
|
|
if(type == PacketType.EstateCovenantRequest) return new EstateCovenantRequestPacket();
|
|
if(type == PacketType.EstateCovenantReply) return new EstateCovenantReplyPacket();
|
|
if(type == PacketType.ForceObjectSelect) return new ForceObjectSelectPacket();
|
|
if(type == PacketType.ParcelBuyPass) return new ParcelBuyPassPacket();
|
|
if(type == PacketType.ParcelDeedToGroup) return new ParcelDeedToGroupPacket();
|
|
if(type == PacketType.ParcelReclaim) return new ParcelReclaimPacket();
|
|
if(type == PacketType.ParcelClaim) return new ParcelClaimPacket();
|
|
if(type == PacketType.ParcelJoin) return new ParcelJoinPacket();
|
|
if(type == PacketType.ParcelDivide) return new ParcelDividePacket();
|
|
if(type == PacketType.ParcelRelease) return new ParcelReleasePacket();
|
|
if(type == PacketType.ParcelBuy) return new ParcelBuyPacket();
|
|
if(type == PacketType.ParcelGodForceOwner) return new ParcelGodForceOwnerPacket();
|
|
if(type == PacketType.ParcelAccessListRequest) return new ParcelAccessListRequestPacket();
|
|
if(type == PacketType.ParcelAccessListReply) return new ParcelAccessListReplyPacket();
|
|
if(type == PacketType.ParcelAccessListUpdate) return new ParcelAccessListUpdatePacket();
|
|
if(type == PacketType.ParcelDwellRequest) return new ParcelDwellRequestPacket();
|
|
if(type == PacketType.ParcelDwellReply) return new ParcelDwellReplyPacket();
|
|
if(type == PacketType.ParcelGodMarkAsContent) return new ParcelGodMarkAsContentPacket();
|
|
if(type == PacketType.ViewerStartAuction) return new ViewerStartAuctionPacket();
|
|
if(type == PacketType.UUIDNameRequest) return new UUIDNameRequestPacket();
|
|
if(type == PacketType.UUIDNameReply) return new UUIDNameReplyPacket();
|
|
if(type == PacketType.UUIDGroupNameRequest) return new UUIDGroupNameRequestPacket();
|
|
if(type == PacketType.UUIDGroupNameReply) return new UUIDGroupNameReplyPacket();
|
|
if(type == PacketType.ChildAgentDying) return new ChildAgentDyingPacket();
|
|
if(type == PacketType.ChildAgentUnknown) return new ChildAgentUnknownPacket();
|
|
if(type == PacketType.GetScriptRunning) return new GetScriptRunningPacket();
|
|
if(type == PacketType.ScriptRunningReply) return new ScriptRunningReplyPacket();
|
|
if(type == PacketType.SetScriptRunning) return new SetScriptRunningPacket();
|
|
if(type == PacketType.ScriptReset) return new ScriptResetPacket();
|
|
if(type == PacketType.ScriptSensorRequest) return new ScriptSensorRequestPacket();
|
|
if(type == PacketType.ScriptSensorReply) return new ScriptSensorReplyPacket();
|
|
if(type == PacketType.CompleteAgentMovement) return new CompleteAgentMovementPacket();
|
|
if(type == PacketType.AgentMovementComplete) return new AgentMovementCompletePacket();
|
|
if(type == PacketType.LogoutRequest) return new LogoutRequestPacket();
|
|
if(type == PacketType.LogoutReply) return new LogoutReplyPacket();
|
|
if(type == PacketType.ImprovedInstantMessage) return new ImprovedInstantMessagePacket();
|
|
if(type == PacketType.RetrieveInstantMessages) return new RetrieveInstantMessagesPacket();
|
|
if(type == PacketType.FindAgent) return new FindAgentPacket();
|
|
if(type == PacketType.RequestGodlikePowers) return new RequestGodlikePowersPacket();
|
|
if(type == PacketType.GrantGodlikePowers) return new GrantGodlikePowersPacket();
|
|
if(type == PacketType.GodlikeMessage) return new GodlikeMessagePacket();
|
|
if(type == PacketType.EstateOwnerMessage) return new EstateOwnerMessagePacket();
|
|
if(type == PacketType.GenericMessage) return new GenericMessagePacket();
|
|
if(type == PacketType.MuteListRequest) return new MuteListRequestPacket();
|
|
if(type == PacketType.UpdateMuteListEntry) return new UpdateMuteListEntryPacket();
|
|
if(type == PacketType.RemoveMuteListEntry) return new RemoveMuteListEntryPacket();
|
|
if(type == PacketType.CopyInventoryFromNotecard) return new CopyInventoryFromNotecardPacket();
|
|
if(type == PacketType.UpdateInventoryItem) return new UpdateInventoryItemPacket();
|
|
if(type == PacketType.UpdateCreateInventoryItem) return new UpdateCreateInventoryItemPacket();
|
|
if(type == PacketType.MoveInventoryItem) return new MoveInventoryItemPacket();
|
|
if(type == PacketType.CopyInventoryItem) return new CopyInventoryItemPacket();
|
|
if(type == PacketType.RemoveInventoryItem) return new RemoveInventoryItemPacket();
|
|
if(type == PacketType.ChangeInventoryItemFlags) return new ChangeInventoryItemFlagsPacket();
|
|
if(type == PacketType.SaveAssetIntoInventory) return new SaveAssetIntoInventoryPacket();
|
|
if(type == PacketType.CreateInventoryFolder) return new CreateInventoryFolderPacket();
|
|
if(type == PacketType.UpdateInventoryFolder) return new UpdateInventoryFolderPacket();
|
|
if(type == PacketType.MoveInventoryFolder) return new MoveInventoryFolderPacket();
|
|
if(type == PacketType.RemoveInventoryFolder) return new RemoveInventoryFolderPacket();
|
|
if(type == PacketType.FetchInventoryDescendents) return new FetchInventoryDescendentsPacket();
|
|
if(type == PacketType.InventoryDescendents) return new InventoryDescendentsPacket();
|
|
if(type == PacketType.FetchInventory) return new FetchInventoryPacket();
|
|
if(type == PacketType.FetchInventoryReply) return new FetchInventoryReplyPacket();
|
|
if(type == PacketType.BulkUpdateInventory) return new BulkUpdateInventoryPacket();
|
|
if(type == PacketType.RemoveInventoryObjects) return new RemoveInventoryObjectsPacket();
|
|
if(type == PacketType.PurgeInventoryDescendents) return new PurgeInventoryDescendentsPacket();
|
|
if(type == PacketType.UpdateTaskInventory) return new UpdateTaskInventoryPacket();
|
|
if(type == PacketType.RemoveTaskInventory) return new RemoveTaskInventoryPacket();
|
|
if(type == PacketType.MoveTaskInventory) return new MoveTaskInventoryPacket();
|
|
if(type == PacketType.RequestTaskInventory) return new RequestTaskInventoryPacket();
|
|
if(type == PacketType.ReplyTaskInventory) return new ReplyTaskInventoryPacket();
|
|
if(type == PacketType.DeRezObject) return new DeRezObjectPacket();
|
|
if(type == PacketType.DeRezAck) return new DeRezAckPacket();
|
|
if(type == PacketType.RezObject) return new RezObjectPacket();
|
|
if(type == PacketType.RezObjectFromNotecard) return new RezObjectFromNotecardPacket();
|
|
if(type == PacketType.AcceptFriendship) return new AcceptFriendshipPacket();
|
|
if(type == PacketType.DeclineFriendship) return new DeclineFriendshipPacket();
|
|
if(type == PacketType.TerminateFriendship) return new TerminateFriendshipPacket();
|
|
if(type == PacketType.OfferCallingCard) return new OfferCallingCardPacket();
|
|
if(type == PacketType.AcceptCallingCard) return new AcceptCallingCardPacket();
|
|
if(type == PacketType.DeclineCallingCard) return new DeclineCallingCardPacket();
|
|
if(type == PacketType.RezScript) return new RezScriptPacket();
|
|
if(type == PacketType.CreateInventoryItem) return new CreateInventoryItemPacket();
|
|
if(type == PacketType.CreateLandmarkForEvent) return new CreateLandmarkForEventPacket();
|
|
if(type == PacketType.RegionHandleRequest) return new RegionHandleRequestPacket();
|
|
if(type == PacketType.RegionIDAndHandleReply) return new RegionIDAndHandleReplyPacket();
|
|
if(type == PacketType.MoneyTransferRequest) return new MoneyTransferRequestPacket();
|
|
if(type == PacketType.MoneyBalanceRequest) return new MoneyBalanceRequestPacket();
|
|
if(type == PacketType.MoneyBalanceReply) return new MoneyBalanceReplyPacket();
|
|
if(type == PacketType.RoutedMoneyBalanceReply) return new RoutedMoneyBalanceReplyPacket();
|
|
if(type == PacketType.ActivateGestures) return new ActivateGesturesPacket();
|
|
if(type == PacketType.DeactivateGestures) return new DeactivateGesturesPacket();
|
|
if(type == PacketType.MuteListUpdate) return new MuteListUpdatePacket();
|
|
if(type == PacketType.UseCachedMuteList) return new UseCachedMuteListPacket();
|
|
if(type == PacketType.GrantUserRights) return new GrantUserRightsPacket();
|
|
if(type == PacketType.ChangeUserRights) return new ChangeUserRightsPacket();
|
|
if(type == PacketType.OnlineNotification) return new OnlineNotificationPacket();
|
|
if(type == PacketType.OfflineNotification) return new OfflineNotificationPacket();
|
|
if(type == PacketType.SetStartLocationRequest) return new SetStartLocationRequestPacket();
|
|
if(type == PacketType.AssetUploadRequest) return new AssetUploadRequestPacket();
|
|
if(type == PacketType.AssetUploadComplete) return new AssetUploadCompletePacket();
|
|
if(type == PacketType.CreateGroupRequest) return new CreateGroupRequestPacket();
|
|
if(type == PacketType.CreateGroupReply) return new CreateGroupReplyPacket();
|
|
if(type == PacketType.UpdateGroupInfo) return new UpdateGroupInfoPacket();
|
|
if(type == PacketType.GroupRoleChanges) return new GroupRoleChangesPacket();
|
|
if(type == PacketType.JoinGroupRequest) return new JoinGroupRequestPacket();
|
|
if(type == PacketType.JoinGroupReply) return new JoinGroupReplyPacket();
|
|
if(type == PacketType.EjectGroupMemberRequest) return new EjectGroupMemberRequestPacket();
|
|
if(type == PacketType.EjectGroupMemberReply) return new EjectGroupMemberReplyPacket();
|
|
if(type == PacketType.LeaveGroupRequest) return new LeaveGroupRequestPacket();
|
|
if(type == PacketType.LeaveGroupReply) return new LeaveGroupReplyPacket();
|
|
if(type == PacketType.InviteGroupRequest) return new InviteGroupRequestPacket();
|
|
if(type == PacketType.GroupProfileRequest) return new GroupProfileRequestPacket();
|
|
if(type == PacketType.GroupProfileReply) return new GroupProfileReplyPacket();
|
|
if(type == PacketType.GroupAccountSummaryRequest) return new GroupAccountSummaryRequestPacket();
|
|
if(type == PacketType.GroupAccountSummaryReply) return new GroupAccountSummaryReplyPacket();
|
|
if(type == PacketType.GroupAccountDetailsRequest) return new GroupAccountDetailsRequestPacket();
|
|
if(type == PacketType.GroupAccountDetailsReply) return new GroupAccountDetailsReplyPacket();
|
|
if(type == PacketType.GroupAccountTransactionsRequest) return new GroupAccountTransactionsRequestPacket();
|
|
if(type == PacketType.GroupAccountTransactionsReply) return new GroupAccountTransactionsReplyPacket();
|
|
if(type == PacketType.GroupActiveProposalsRequest) return new GroupActiveProposalsRequestPacket();
|
|
if(type == PacketType.GroupActiveProposalItemReply) return new GroupActiveProposalItemReplyPacket();
|
|
if(type == PacketType.GroupVoteHistoryRequest) return new GroupVoteHistoryRequestPacket();
|
|
if(type == PacketType.GroupVoteHistoryItemReply) return new GroupVoteHistoryItemReplyPacket();
|
|
if(type == PacketType.StartGroupProposal) return new StartGroupProposalPacket();
|
|
if(type == PacketType.GroupProposalBallot) return new GroupProposalBallotPacket();
|
|
if(type == PacketType.GroupMembersRequest) return new GroupMembersRequestPacket();
|
|
if(type == PacketType.GroupMembersReply) return new GroupMembersReplyPacket();
|
|
if(type == PacketType.ActivateGroup) return new ActivateGroupPacket();
|
|
if(type == PacketType.SetGroupContribution) return new SetGroupContributionPacket();
|
|
if(type == PacketType.SetGroupAcceptNotices) return new SetGroupAcceptNoticesPacket();
|
|
if(type == PacketType.GroupRoleDataRequest) return new GroupRoleDataRequestPacket();
|
|
if(type == PacketType.GroupRoleDataReply) return new GroupRoleDataReplyPacket();
|
|
if(type == PacketType.GroupRoleMembersRequest) return new GroupRoleMembersRequestPacket();
|
|
if(type == PacketType.GroupRoleMembersReply) return new GroupRoleMembersReplyPacket();
|
|
if(type == PacketType.GroupTitlesRequest) return new GroupTitlesRequestPacket();
|
|
if(type == PacketType.GroupTitlesReply) return new GroupTitlesReplyPacket();
|
|
if(type == PacketType.GroupTitleUpdate) return new GroupTitleUpdatePacket();
|
|
if(type == PacketType.GroupRoleUpdate) return new GroupRoleUpdatePacket();
|
|
if(type == PacketType.LiveHelpGroupRequest) return new LiveHelpGroupRequestPacket();
|
|
if(type == PacketType.LiveHelpGroupReply) return new LiveHelpGroupReplyPacket();
|
|
if(type == PacketType.AgentWearablesRequest) return new AgentWearablesRequestPacket();
|
|
if(type == PacketType.AgentWearablesUpdate) return new AgentWearablesUpdatePacket();
|
|
if(type == PacketType.AgentIsNowWearing) return new AgentIsNowWearingPacket();
|
|
if(type == PacketType.AgentCachedTexture) return new AgentCachedTexturePacket();
|
|
if(type == PacketType.AgentCachedTextureResponse) return new AgentCachedTextureResponsePacket();
|
|
if(type == PacketType.AgentDataUpdateRequest) return new AgentDataUpdateRequestPacket();
|
|
if(type == PacketType.AgentDataUpdate) return new AgentDataUpdatePacket();
|
|
if(type == PacketType.GroupDataUpdate) return new GroupDataUpdatePacket();
|
|
if(type == PacketType.AgentGroupDataUpdate) return new AgentGroupDataUpdatePacket();
|
|
if(type == PacketType.AgentDropGroup) return new AgentDropGroupPacket();
|
|
if(type == PacketType.RezSingleAttachmentFromInv) return new RezSingleAttachmentFromInvPacket();
|
|
if(type == PacketType.RezMultipleAttachmentsFromInv) return new RezMultipleAttachmentsFromInvPacket();
|
|
if(type == PacketType.DetachAttachmentIntoInv) return new DetachAttachmentIntoInvPacket();
|
|
if(type == PacketType.CreateNewOutfitAttachments) return new CreateNewOutfitAttachmentsPacket();
|
|
if(type == PacketType.UserInfoRequest) return new UserInfoRequestPacket();
|
|
if(type == PacketType.UserInfoReply) return new UserInfoReplyPacket();
|
|
if(type == PacketType.UpdateUserInfo) return new UpdateUserInfoPacket();
|
|
if(type == PacketType.InitiateDownload) return new InitiateDownloadPacket();
|
|
if(type == PacketType.MapLayerRequest) return new MapLayerRequestPacket();
|
|
if(type == PacketType.MapLayerReply) return new MapLayerReplyPacket();
|
|
if(type == PacketType.MapBlockRequest) return new MapBlockRequestPacket();
|
|
if(type == PacketType.MapNameRequest) return new MapNameRequestPacket();
|
|
if(type == PacketType.MapBlockReply) return new MapBlockReplyPacket();
|
|
if(type == PacketType.MapItemRequest) return new MapItemRequestPacket();
|
|
if(type == PacketType.MapItemReply) return new MapItemReplyPacket();
|
|
if(type == PacketType.SendPostcard) return new SendPostcardPacket();
|
|
if(type == PacketType.ParcelMediaCommandMessage) return new ParcelMediaCommandMessagePacket();
|
|
if(type == PacketType.ParcelMediaUpdate) return new ParcelMediaUpdatePacket();
|
|
if(type == PacketType.LandStatRequest) return new LandStatRequestPacket();
|
|
if(type == PacketType.LandStatReply) return new LandStatReplyPacket();
|
|
if(type == PacketType.Error) return new ErrorPacket();
|
|
if(type == PacketType.ObjectIncludeInSearch) return new ObjectIncludeInSearchPacket();
|
|
if(type == PacketType.RezRestoreToWorld) return new RezRestoreToWorldPacket();
|
|
if(type == PacketType.LinkInventoryItem) return new LinkInventoryItemPacket();
|
|
if(type == PacketType.RetrieveIMsExtended) return new RetrieveIMsExtendedPacket();
|
|
if(type == PacketType.JoinGroupRequestExtended) return new JoinGroupRequestExtendedPacket();
|
|
if(type == PacketType.CreateGroupRequestExtended) return new CreateGroupRequestExtendedPacket();
|
|
if(type == PacketType.LargeGenericMessage) return new LargeGenericMessagePacket();
|
|
if(type == PacketType.PacketAck) return new PacketAckPacket();
|
|
if(type == PacketType.OpenCircuit) return new OpenCircuitPacket();
|
|
if(type == PacketType.CloseCircuit) return new CloseCircuitPacket();
|
|
return null;
|
|
|
|
}
|
|
|
|
public static Packet BuildPacket(byte[] packetBuffer, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
byte[] bytes;
|
|
int i = 0;
|
|
Header header = Header.BuildHeader(packetBuffer, ref i, ref packetEnd);
|
|
if (header.Zerocoded)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(packetBuffer, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
else
|
|
{
|
|
bytes = packetBuffer;
|
|
}
|
|
Array.Clear(bytes, packetEnd + 1, bytes.Length - packetEnd - 1);
|
|
|
|
switch (header.Frequency)
|
|
{
|
|
case PacketFrequency.Low:
|
|
switch (header.ID)
|
|
{
|
|
case 1: return new TestMessagePacket(header, bytes, ref i);
|
|
case 3: return new UseCircuitCodePacket(header, bytes, ref i);
|
|
case 10: return new TelehubInfoPacket(header, bytes, ref i);
|
|
case 24: return new EconomyDataRequestPacket(header, bytes, ref i);
|
|
case 25: return new EconomyDataPacket(header, bytes, ref i);
|
|
case 26: return new AvatarPickerRequestPacket(header, bytes, ref i);
|
|
case 28: return new AvatarPickerReplyPacket(header, bytes, ref i);
|
|
case 29: return new PlacesQueryPacket(header, bytes, ref i);
|
|
case 30: return new PlacesReplyPacket(header, bytes, ref i);
|
|
case 31: return new DirFindQueryPacket(header, bytes, ref i);
|
|
case 33: return new DirPlacesQueryPacket(header, bytes, ref i);
|
|
case 35: return new DirPlacesReplyPacket(header, bytes, ref i);
|
|
case 36: return new DirPeopleReplyPacket(header, bytes, ref i);
|
|
case 37: return new DirEventsReplyPacket(header, bytes, ref i);
|
|
case 38: return new DirGroupsReplyPacket(header, bytes, ref i);
|
|
case 39: return new DirClassifiedQueryPacket(header, bytes, ref i);
|
|
case 41: return new DirClassifiedReplyPacket(header, bytes, ref i);
|
|
case 42: return new AvatarClassifiedReplyPacket(header, bytes, ref i);
|
|
case 43: return new ClassifiedInfoRequestPacket(header, bytes, ref i);
|
|
case 44: return new ClassifiedInfoReplyPacket(header, bytes, ref i);
|
|
case 45: return new ClassifiedInfoUpdatePacket(header, bytes, ref i);
|
|
case 46: return new ClassifiedDeletePacket(header, bytes, ref i);
|
|
case 47: return new ClassifiedGodDeletePacket(header, bytes, ref i);
|
|
case 48: return new DirLandQueryPacket(header, bytes, ref i);
|
|
case 50: return new DirLandReplyPacket(header, bytes, ref i);
|
|
case 51: return new DirPopularQueryPacket(header, bytes, ref i);
|
|
case 53: return new DirPopularReplyPacket(header, bytes, ref i);
|
|
case 54: return new ParcelInfoRequestPacket(header, bytes, ref i);
|
|
case 55: return new ParcelInfoReplyPacket(header, bytes, ref i);
|
|
case 56: return new ParcelObjectOwnersRequestPacket(header, bytes, ref i);
|
|
case 57: return new ParcelObjectOwnersReplyPacket(header, bytes, ref i);
|
|
case 58: return new GroupNoticesListRequestPacket(header, bytes, ref i);
|
|
case 59: return new GroupNoticesListReplyPacket(header, bytes, ref i);
|
|
case 60: return new GroupNoticeRequestPacket(header, bytes, ref i);
|
|
case 62: return new TeleportRequestPacket(header, bytes, ref i);
|
|
case 63: return new TeleportLocationRequestPacket(header, bytes, ref i);
|
|
case 64: return new TeleportLocalPacket(header, bytes, ref i);
|
|
case 65: return new TeleportLandmarkRequestPacket(header, bytes, ref i);
|
|
case 66: return new TeleportProgressPacket(header, bytes, ref i);
|
|
case 69: return new TeleportFinishPacket(header, bytes, ref i);
|
|
case 70: return new StartLurePacket(header, bytes, ref i);
|
|
case 71: return new TeleportLureRequestPacket(header, bytes, ref i);
|
|
case 72: return new TeleportCancelPacket(header, bytes, ref i);
|
|
case 73: return new TeleportStartPacket(header, bytes, ref i);
|
|
case 74: return new TeleportFailedPacket(header, bytes, ref i);
|
|
case 75: return new UndoPacket(header, bytes, ref i);
|
|
case 76: return new RedoPacket(header, bytes, ref i);
|
|
case 77: return new UndoLandPacket(header, bytes, ref i);
|
|
case 78: return new AgentPausePacket(header, bytes, ref i);
|
|
case 79: return new AgentResumePacket(header, bytes, ref i);
|
|
case 80: return new ChatFromViewerPacket(header, bytes, ref i);
|
|
case 81: return new AgentThrottlePacket(header, bytes, ref i);
|
|
case 82: return new AgentFOVPacket(header, bytes, ref i);
|
|
case 83: return new AgentHeightWidthPacket(header, bytes, ref i);
|
|
case 84: return new AgentSetAppearancePacket(header, bytes, ref i);
|
|
case 85: return new AgentQuitCopyPacket(header, bytes, ref i);
|
|
case 86: return new ImageNotInDatabasePacket(header, bytes, ref i);
|
|
case 87: return new RebakeAvatarTexturesPacket(header, bytes, ref i);
|
|
case 88: return new SetAlwaysRunPacket(header, bytes, ref i);
|
|
case 89: return new ObjectDeletePacket(header, bytes, ref i);
|
|
case 90: return new ObjectDuplicatePacket(header, bytes, ref i);
|
|
case 91: return new ObjectDuplicateOnRayPacket(header, bytes, ref i);
|
|
case 92: return new ObjectScalePacket(header, bytes, ref i);
|
|
case 93: return new ObjectRotationPacket(header, bytes, ref i);
|
|
case 94: return new ObjectFlagUpdatePacket(header, bytes, ref i);
|
|
case 95: return new ObjectClickActionPacket(header, bytes, ref i);
|
|
case 96: return new ObjectImagePacket(header, bytes, ref i);
|
|
case 97: return new ObjectMaterialPacket(header, bytes, ref i);
|
|
case 98: return new ObjectShapePacket(header, bytes, ref i);
|
|
case 99: return new ObjectExtraParamsPacket(header, bytes, ref i);
|
|
case 100: return new ObjectOwnerPacket(header, bytes, ref i);
|
|
case 101: return new ObjectGroupPacket(header, bytes, ref i);
|
|
case 102: return new ObjectBuyPacket(header, bytes, ref i);
|
|
case 103: return new BuyObjectInventoryPacket(header, bytes, ref i);
|
|
case 104: return new DerezContainerPacket(header, bytes, ref i);
|
|
case 105: return new ObjectPermissionsPacket(header, bytes, ref i);
|
|
case 106: return new ObjectSaleInfoPacket(header, bytes, ref i);
|
|
case 107: return new ObjectNamePacket(header, bytes, ref i);
|
|
case 108: return new ObjectDescriptionPacket(header, bytes, ref i);
|
|
case 109: return new ObjectCategoryPacket(header, bytes, ref i);
|
|
case 110: return new ObjectSelectPacket(header, bytes, ref i);
|
|
case 111: return new ObjectDeselectPacket(header, bytes, ref i);
|
|
case 112: return new ObjectAttachPacket(header, bytes, ref i);
|
|
case 113: return new ObjectDetachPacket(header, bytes, ref i);
|
|
case 114: return new ObjectDropPacket(header, bytes, ref i);
|
|
case 115: return new ObjectLinkPacket(header, bytes, ref i);
|
|
case 116: return new ObjectDelinkPacket(header, bytes, ref i);
|
|
case 117: return new ObjectGrabPacket(header, bytes, ref i);
|
|
case 118: return new ObjectGrabUpdatePacket(header, bytes, ref i);
|
|
case 119: return new ObjectDeGrabPacket(header, bytes, ref i);
|
|
case 120: return new ObjectSpinStartPacket(header, bytes, ref i);
|
|
case 121: return new ObjectSpinUpdatePacket(header, bytes, ref i);
|
|
case 122: return new ObjectSpinStopPacket(header, bytes, ref i);
|
|
case 123: return new ObjectExportSelectedPacket(header, bytes, ref i);
|
|
case 124: return new ModifyLandPacket(header, bytes, ref i);
|
|
case 125: return new VelocityInterpolateOnPacket(header, bytes, ref i);
|
|
case 126: return new VelocityInterpolateOffPacket(header, bytes, ref i);
|
|
case 127: return new StateSavePacket(header, bytes, ref i);
|
|
case 128: return new ReportAutosaveCrashPacket(header, bytes, ref i);
|
|
case 129: return new SimWideDeletesPacket(header, bytes, ref i);
|
|
case 130: return new TrackAgentPacket(header, bytes, ref i);
|
|
case 131: return new ViewerStatsPacket(header, bytes, ref i);
|
|
case 132: return new ScriptAnswerYesPacket(header, bytes, ref i);
|
|
case 133: return new UserReportPacket(header, bytes, ref i);
|
|
case 134: return new AlertMessagePacket(header, bytes, ref i);
|
|
case 135: return new AgentAlertMessagePacket(header, bytes, ref i);
|
|
case 136: return new MeanCollisionAlertPacket(header, bytes, ref i);
|
|
case 137: return new ViewerFrozenMessagePacket(header, bytes, ref i);
|
|
case 138: return new HealthMessagePacket(header, bytes, ref i);
|
|
case 139: return new ChatFromSimulatorPacket(header, bytes, ref i);
|
|
case 140: return new SimStatsPacket(header, bytes, ref i);
|
|
case 141: return new RequestRegionInfoPacket(header, bytes, ref i);
|
|
case 142: return new RegionInfoPacket(header, bytes, ref i);
|
|
case 143: return new GodUpdateRegionInfoPacket(header, bytes, ref i);
|
|
case 148: return new RegionHandshakePacket(header, bytes, ref i);
|
|
case 149: return new RegionHandshakeReplyPacket(header, bytes, ref i);
|
|
case 150: return new SimulatorViewerTimeMessagePacket(header, bytes, ref i);
|
|
case 151: return new EnableSimulatorPacket(header, bytes, ref i);
|
|
case 152: return new DisableSimulatorPacket(header, bytes, ref i);
|
|
case 153: return new TransferRequestPacket(header, bytes, ref i);
|
|
case 154: return new TransferInfoPacket(header, bytes, ref i);
|
|
case 155: return new TransferAbortPacket(header, bytes, ref i);
|
|
case 156: return new RequestXferPacket(header, bytes, ref i);
|
|
case 157: return new AbortXferPacket(header, bytes, ref i);
|
|
case 158: return new AvatarAppearancePacket(header, bytes, ref i);
|
|
case 159: return new SetFollowCamPropertiesPacket(header, bytes, ref i);
|
|
case 160: return new ClearFollowCamPropertiesPacket(header, bytes, ref i);
|
|
case 161: return new RequestPayPricePacket(header, bytes, ref i);
|
|
case 162: return new PayPriceReplyPacket(header, bytes, ref i);
|
|
case 163: return new KickUserPacket(header, bytes, ref i);
|
|
case 165: return new GodKickUserPacket(header, bytes, ref i);
|
|
case 167: return new EjectUserPacket(header, bytes, ref i);
|
|
case 168: return new FreezeUserPacket(header, bytes, ref i);
|
|
case 169: return new AvatarPropertiesRequestPacket(header, bytes, ref i);
|
|
case 171: return new AvatarPropertiesReplyPacket(header, bytes, ref i);
|
|
case 172: return new AvatarInterestsReplyPacket(header, bytes, ref i);
|
|
case 173: return new AvatarGroupsReplyPacket(header, bytes, ref i);
|
|
case 174: return new AvatarPropertiesUpdatePacket(header, bytes, ref i);
|
|
case 175: return new AvatarInterestsUpdatePacket(header, bytes, ref i);
|
|
case 176: return new AvatarNotesReplyPacket(header, bytes, ref i);
|
|
case 177: return new AvatarNotesUpdatePacket(header, bytes, ref i);
|
|
case 178: return new AvatarPicksReplyPacket(header, bytes, ref i);
|
|
case 179: return new EventInfoRequestPacket(header, bytes, ref i);
|
|
case 180: return new EventInfoReplyPacket(header, bytes, ref i);
|
|
case 181: return new EventNotificationAddRequestPacket(header, bytes, ref i);
|
|
case 182: return new EventNotificationRemoveRequestPacket(header, bytes, ref i);
|
|
case 183: return new EventGodDeletePacket(header, bytes, ref i);
|
|
case 184: return new PickInfoReplyPacket(header, bytes, ref i);
|
|
case 185: return new PickInfoUpdatePacket(header, bytes, ref i);
|
|
case 186: return new PickDeletePacket(header, bytes, ref i);
|
|
case 187: return new PickGodDeletePacket(header, bytes, ref i);
|
|
case 188: return new ScriptQuestionPacket(header, bytes, ref i);
|
|
case 189: return new ScriptControlChangePacket(header, bytes, ref i);
|
|
case 190: return new ScriptDialogPacket(header, bytes, ref i);
|
|
case 191: return new ScriptDialogReplyPacket(header, bytes, ref i);
|
|
case 192: return new ForceScriptControlReleasePacket(header, bytes, ref i);
|
|
case 193: return new RevokePermissionsPacket(header, bytes, ref i);
|
|
case 194: return new LoadURLPacket(header, bytes, ref i);
|
|
case 195: return new ScriptTeleportRequestPacket(header, bytes, ref i);
|
|
case 196: return new ParcelOverlayPacket(header, bytes, ref i);
|
|
case 197: return new ParcelPropertiesRequestByIDPacket(header, bytes, ref i);
|
|
case 198: return new ParcelPropertiesUpdatePacket(header, bytes, ref i);
|
|
case 199: return new ParcelReturnObjectsPacket(header, bytes, ref i);
|
|
case 200: return new ParcelSetOtherCleanTimePacket(header, bytes, ref i);
|
|
case 201: return new ParcelDisableObjectsPacket(header, bytes, ref i);
|
|
case 202: return new ParcelSelectObjectsPacket(header, bytes, ref i);
|
|
case 203: return new EstateCovenantRequestPacket(header, bytes, ref i);
|
|
case 204: return new EstateCovenantReplyPacket(header, bytes, ref i);
|
|
case 205: return new ForceObjectSelectPacket(header, bytes, ref i);
|
|
case 206: return new ParcelBuyPassPacket(header, bytes, ref i);
|
|
case 207: return new ParcelDeedToGroupPacket(header, bytes, ref i);
|
|
case 208: return new ParcelReclaimPacket(header, bytes, ref i);
|
|
case 209: return new ParcelClaimPacket(header, bytes, ref i);
|
|
case 210: return new ParcelJoinPacket(header, bytes, ref i);
|
|
case 211: return new ParcelDividePacket(header, bytes, ref i);
|
|
case 212: return new ParcelReleasePacket(header, bytes, ref i);
|
|
case 213: return new ParcelBuyPacket(header, bytes, ref i);
|
|
case 214: return new ParcelGodForceOwnerPacket(header, bytes, ref i);
|
|
case 215: return new ParcelAccessListRequestPacket(header, bytes, ref i);
|
|
case 216: return new ParcelAccessListReplyPacket(header, bytes, ref i);
|
|
case 217: return new ParcelAccessListUpdatePacket(header, bytes, ref i);
|
|
case 218: return new ParcelDwellRequestPacket(header, bytes, ref i);
|
|
case 219: return new ParcelDwellReplyPacket(header, bytes, ref i);
|
|
case 227: return new ParcelGodMarkAsContentPacket(header, bytes, ref i);
|
|
case 228: return new ViewerStartAuctionPacket(header, bytes, ref i);
|
|
case 235: return new UUIDNameRequestPacket(header, bytes, ref i);
|
|
case 236: return new UUIDNameReplyPacket(header, bytes, ref i);
|
|
case 237: return new UUIDGroupNameRequestPacket(header, bytes, ref i);
|
|
case 238: return new UUIDGroupNameReplyPacket(header, bytes, ref i);
|
|
case 240: return new ChildAgentDyingPacket(header, bytes, ref i);
|
|
case 241: return new ChildAgentUnknownPacket(header, bytes, ref i);
|
|
case 243: return new GetScriptRunningPacket(header, bytes, ref i);
|
|
case 244: return new ScriptRunningReplyPacket(header, bytes, ref i);
|
|
case 245: return new SetScriptRunningPacket(header, bytes, ref i);
|
|
case 246: return new ScriptResetPacket(header, bytes, ref i);
|
|
case 247: return new ScriptSensorRequestPacket(header, bytes, ref i);
|
|
case 248: return new ScriptSensorReplyPacket(header, bytes, ref i);
|
|
case 249: return new CompleteAgentMovementPacket(header, bytes, ref i);
|
|
case 250: return new AgentMovementCompletePacket(header, bytes, ref i);
|
|
case 252: return new LogoutRequestPacket(header, bytes, ref i);
|
|
case 253: return new LogoutReplyPacket(header, bytes, ref i);
|
|
case 254: return new ImprovedInstantMessagePacket(header, bytes, ref i);
|
|
case 255: return new RetrieveInstantMessagesPacket(header, bytes, ref i);
|
|
case 256: return new FindAgentPacket(header, bytes, ref i);
|
|
case 257: return new RequestGodlikePowersPacket(header, bytes, ref i);
|
|
case 258: return new GrantGodlikePowersPacket(header, bytes, ref i);
|
|
case 259: return new GodlikeMessagePacket(header, bytes, ref i);
|
|
case 260: return new EstateOwnerMessagePacket(header, bytes, ref i);
|
|
case 261: return new GenericMessagePacket(header, bytes, ref i);
|
|
case 262: return new MuteListRequestPacket(header, bytes, ref i);
|
|
case 263: return new UpdateMuteListEntryPacket(header, bytes, ref i);
|
|
case 264: return new RemoveMuteListEntryPacket(header, bytes, ref i);
|
|
case 265: return new CopyInventoryFromNotecardPacket(header, bytes, ref i);
|
|
case 266: return new UpdateInventoryItemPacket(header, bytes, ref i);
|
|
case 267: return new UpdateCreateInventoryItemPacket(header, bytes, ref i);
|
|
case 268: return new MoveInventoryItemPacket(header, bytes, ref i);
|
|
case 269: return new CopyInventoryItemPacket(header, bytes, ref i);
|
|
case 270: return new RemoveInventoryItemPacket(header, bytes, ref i);
|
|
case 271: return new ChangeInventoryItemFlagsPacket(header, bytes, ref i);
|
|
case 272: return new SaveAssetIntoInventoryPacket(header, bytes, ref i);
|
|
case 273: return new CreateInventoryFolderPacket(header, bytes, ref i);
|
|
case 274: return new UpdateInventoryFolderPacket(header, bytes, ref i);
|
|
case 275: return new MoveInventoryFolderPacket(header, bytes, ref i);
|
|
case 276: return new RemoveInventoryFolderPacket(header, bytes, ref i);
|
|
case 277: return new FetchInventoryDescendentsPacket(header, bytes, ref i);
|
|
case 278: return new InventoryDescendentsPacket(header, bytes, ref i);
|
|
case 279: return new FetchInventoryPacket(header, bytes, ref i);
|
|
case 280: return new FetchInventoryReplyPacket(header, bytes, ref i);
|
|
case 281: return new BulkUpdateInventoryPacket(header, bytes, ref i);
|
|
case 284: return new RemoveInventoryObjectsPacket(header, bytes, ref i);
|
|
case 285: return new PurgeInventoryDescendentsPacket(header, bytes, ref i);
|
|
case 286: return new UpdateTaskInventoryPacket(header, bytes, ref i);
|
|
case 287: return new RemoveTaskInventoryPacket(header, bytes, ref i);
|
|
case 288: return new MoveTaskInventoryPacket(header, bytes, ref i);
|
|
case 289: return new RequestTaskInventoryPacket(header, bytes, ref i);
|
|
case 290: return new ReplyTaskInventoryPacket(header, bytes, ref i);
|
|
case 291: return new DeRezObjectPacket(header, bytes, ref i);
|
|
case 292: return new DeRezAckPacket(header, bytes, ref i);
|
|
case 293: return new RezObjectPacket(header, bytes, ref i);
|
|
case 294: return new RezObjectFromNotecardPacket(header, bytes, ref i);
|
|
case 297: return new AcceptFriendshipPacket(header, bytes, ref i);
|
|
case 298: return new DeclineFriendshipPacket(header, bytes, ref i);
|
|
case 300: return new TerminateFriendshipPacket(header, bytes, ref i);
|
|
case 301: return new OfferCallingCardPacket(header, bytes, ref i);
|
|
case 302: return new AcceptCallingCardPacket(header, bytes, ref i);
|
|
case 303: return new DeclineCallingCardPacket(header, bytes, ref i);
|
|
case 304: return new RezScriptPacket(header, bytes, ref i);
|
|
case 305: return new CreateInventoryItemPacket(header, bytes, ref i);
|
|
case 306: return new CreateLandmarkForEventPacket(header, bytes, ref i);
|
|
case 309: return new RegionHandleRequestPacket(header, bytes, ref i);
|
|
case 310: return new RegionIDAndHandleReplyPacket(header, bytes, ref i);
|
|
case 311: return new MoneyTransferRequestPacket(header, bytes, ref i);
|
|
case 313: return new MoneyBalanceRequestPacket(header, bytes, ref i);
|
|
case 314: return new MoneyBalanceReplyPacket(header, bytes, ref i);
|
|
case 315: return new RoutedMoneyBalanceReplyPacket(header, bytes, ref i);
|
|
case 316: return new ActivateGesturesPacket(header, bytes, ref i);
|
|
case 317: return new DeactivateGesturesPacket(header, bytes, ref i);
|
|
case 318: return new MuteListUpdatePacket(header, bytes, ref i);
|
|
case 319: return new UseCachedMuteListPacket(header, bytes, ref i);
|
|
case 320: return new GrantUserRightsPacket(header, bytes, ref i);
|
|
case 321: return new ChangeUserRightsPacket(header, bytes, ref i);
|
|
case 322: return new OnlineNotificationPacket(header, bytes, ref i);
|
|
case 323: return new OfflineNotificationPacket(header, bytes, ref i);
|
|
case 324: return new SetStartLocationRequestPacket(header, bytes, ref i);
|
|
case 333: return new AssetUploadRequestPacket(header, bytes, ref i);
|
|
case 334: return new AssetUploadCompletePacket(header, bytes, ref i);
|
|
case 339: return new CreateGroupRequestPacket(header, bytes, ref i);
|
|
case 340: return new CreateGroupReplyPacket(header, bytes, ref i);
|
|
case 341: return new UpdateGroupInfoPacket(header, bytes, ref i);
|
|
case 342: return new GroupRoleChangesPacket(header, bytes, ref i);
|
|
case 343: return new JoinGroupRequestPacket(header, bytes, ref i);
|
|
case 344: return new JoinGroupReplyPacket(header, bytes, ref i);
|
|
case 345: return new EjectGroupMemberRequestPacket(header, bytes, ref i);
|
|
case 346: return new EjectGroupMemberReplyPacket(header, bytes, ref i);
|
|
case 347: return new LeaveGroupRequestPacket(header, bytes, ref i);
|
|
case 348: return new LeaveGroupReplyPacket(header, bytes, ref i);
|
|
case 349: return new InviteGroupRequestPacket(header, bytes, ref i);
|
|
case 351: return new GroupProfileRequestPacket(header, bytes, ref i);
|
|
case 352: return new GroupProfileReplyPacket(header, bytes, ref i);
|
|
case 353: return new GroupAccountSummaryRequestPacket(header, bytes, ref i);
|
|
case 354: return new GroupAccountSummaryReplyPacket(header, bytes, ref i);
|
|
case 355: return new GroupAccountDetailsRequestPacket(header, bytes, ref i);
|
|
case 356: return new GroupAccountDetailsReplyPacket(header, bytes, ref i);
|
|
case 357: return new GroupAccountTransactionsRequestPacket(header, bytes, ref i);
|
|
case 358: return new GroupAccountTransactionsReplyPacket(header, bytes, ref i);
|
|
case 359: return new GroupActiveProposalsRequestPacket(header, bytes, ref i);
|
|
case 360: return new GroupActiveProposalItemReplyPacket(header, bytes, ref i);
|
|
case 361: return new GroupVoteHistoryRequestPacket(header, bytes, ref i);
|
|
case 362: return new GroupVoteHistoryItemReplyPacket(header, bytes, ref i);
|
|
case 363: return new StartGroupProposalPacket(header, bytes, ref i);
|
|
case 364: return new GroupProposalBallotPacket(header, bytes, ref i);
|
|
case 366: return new GroupMembersRequestPacket(header, bytes, ref i);
|
|
case 367: return new GroupMembersReplyPacket(header, bytes, ref i);
|
|
case 368: return new ActivateGroupPacket(header, bytes, ref i);
|
|
case 369: return new SetGroupContributionPacket(header, bytes, ref i);
|
|
case 370: return new SetGroupAcceptNoticesPacket(header, bytes, ref i);
|
|
case 371: return new GroupRoleDataRequestPacket(header, bytes, ref i);
|
|
case 372: return new GroupRoleDataReplyPacket(header, bytes, ref i);
|
|
case 373: return new GroupRoleMembersRequestPacket(header, bytes, ref i);
|
|
case 374: return new GroupRoleMembersReplyPacket(header, bytes, ref i);
|
|
case 375: return new GroupTitlesRequestPacket(header, bytes, ref i);
|
|
case 376: return new GroupTitlesReplyPacket(header, bytes, ref i);
|
|
case 377: return new GroupTitleUpdatePacket(header, bytes, ref i);
|
|
case 378: return new GroupRoleUpdatePacket(header, bytes, ref i);
|
|
case 379: return new LiveHelpGroupRequestPacket(header, bytes, ref i);
|
|
case 380: return new LiveHelpGroupReplyPacket(header, bytes, ref i);
|
|
case 381: return new AgentWearablesRequestPacket(header, bytes, ref i);
|
|
case 382: return new AgentWearablesUpdatePacket(header, bytes, ref i);
|
|
case 383: return new AgentIsNowWearingPacket(header, bytes, ref i);
|
|
case 384: return new AgentCachedTexturePacket(header, bytes, ref i);
|
|
case 385: return new AgentCachedTextureResponsePacket(header, bytes, ref i);
|
|
case 386: return new AgentDataUpdateRequestPacket(header, bytes, ref i);
|
|
case 387: return new AgentDataUpdatePacket(header, bytes, ref i);
|
|
case 388: return new GroupDataUpdatePacket(header, bytes, ref i);
|
|
case 389: return new AgentGroupDataUpdatePacket(header, bytes, ref i);
|
|
case 390: return new AgentDropGroupPacket(header, bytes, ref i);
|
|
case 395: return new RezSingleAttachmentFromInvPacket(header, bytes, ref i);
|
|
case 396: return new RezMultipleAttachmentsFromInvPacket(header, bytes, ref i);
|
|
case 397: return new DetachAttachmentIntoInvPacket(header, bytes, ref i);
|
|
case 398: return new CreateNewOutfitAttachmentsPacket(header, bytes, ref i);
|
|
case 399: return new UserInfoRequestPacket(header, bytes, ref i);
|
|
case 400: return new UserInfoReplyPacket(header, bytes, ref i);
|
|
case 401: return new UpdateUserInfoPacket(header, bytes, ref i);
|
|
case 403: return new InitiateDownloadPacket(header, bytes, ref i);
|
|
case 405: return new MapLayerRequestPacket(header, bytes, ref i);
|
|
case 406: return new MapLayerReplyPacket(header, bytes, ref i);
|
|
case 407: return new MapBlockRequestPacket(header, bytes, ref i);
|
|
case 408: return new MapNameRequestPacket(header, bytes, ref i);
|
|
case 409: return new MapBlockReplyPacket(header, bytes, ref i);
|
|
case 410: return new MapItemRequestPacket(header, bytes, ref i);
|
|
case 411: return new MapItemReplyPacket(header, bytes, ref i);
|
|
case 412: return new SendPostcardPacket(header, bytes, ref i);
|
|
case 419: return new ParcelMediaCommandMessagePacket(header, bytes, ref i);
|
|
case 420: return new ParcelMediaUpdatePacket(header, bytes, ref i);
|
|
case 421: return new LandStatRequestPacket(header, bytes, ref i);
|
|
case 422: return new LandStatReplyPacket(header, bytes, ref i);
|
|
case 423: return new ErrorPacket(header, bytes, ref i);
|
|
case 424: return new ObjectIncludeInSearchPacket(header, bytes, ref i);
|
|
case 425: return new RezRestoreToWorldPacket(header, bytes, ref i);
|
|
case 426: return new LinkInventoryItemPacket(header, bytes, ref i);
|
|
case 427: return new RetrieveIMsExtendedPacket(header, bytes, ref i);
|
|
case 428: return new JoinGroupRequestExtendedPacket(header, bytes, ref i);
|
|
case 429: return new CreateGroupRequestExtendedPacket(header, bytes, ref i);
|
|
case 430: return new LargeGenericMessagePacket(header, bytes, ref i);
|
|
case 65531: return new PacketAckPacket(header, bytes, ref i);
|
|
case 65532: return new OpenCircuitPacket(header, bytes, ref i);
|
|
case 65533: return new CloseCircuitPacket(header, bytes, ref i);
|
|
|
|
}
|
|
break;
|
|
case PacketFrequency.Medium:
|
|
switch (header.ID)
|
|
{
|
|
case 1: return new ObjectAddPacket(header, bytes, ref i);
|
|
case 2: return new MultipleObjectUpdatePacket(header, bytes, ref i);
|
|
case 3: return new RequestMultipleObjectsPacket(header, bytes, ref i);
|
|
case 4: return new ObjectPositionPacket(header, bytes, ref i);
|
|
case 5: return new RequestObjectPropertiesFamilyPacket(header, bytes, ref i);
|
|
case 6: return new CoarseLocationUpdatePacket(header, bytes, ref i);
|
|
case 7: return new CrossedRegionPacket(header, bytes, ref i);
|
|
case 8: return new ConfirmEnableSimulatorPacket(header, bytes, ref i);
|
|
case 9: return new ObjectPropertiesPacket(header, bytes, ref i);
|
|
case 10: return new ObjectPropertiesFamilyPacket(header, bytes, ref i);
|
|
case 11: return new ParcelPropertiesRequestPacket(header, bytes, ref i);
|
|
case 13: return new AttachedSoundPacket(header, bytes, ref i);
|
|
case 14: return new AttachedSoundGainChangePacket(header, bytes, ref i);
|
|
case 15: return new PreloadSoundPacket(header, bytes, ref i);
|
|
case 17: return new ViewerEffectPacket(header, bytes, ref i);
|
|
|
|
}
|
|
break;
|
|
case PacketFrequency.High:
|
|
switch (header.ID)
|
|
{
|
|
case 1: return new StartPingCheckPacket(header, bytes, ref i);
|
|
case 2: return new CompletePingCheckPacket(header, bytes, ref i);
|
|
case 4: return new AgentUpdatePacket(header, bytes, ref i);
|
|
case 5: return new AgentAnimationPacket(header, bytes, ref i);
|
|
case 6: return new AgentRequestSitPacket(header, bytes, ref i);
|
|
case 7: return new AgentSitPacket(header, bytes, ref i);
|
|
case 8: return new RequestImagePacket(header, bytes, ref i);
|
|
case 9: return new ImageDataPacket(header, bytes, ref i);
|
|
case 10: return new ImagePacketPacket(header, bytes, ref i);
|
|
case 11: return new LayerDataPacket(header, bytes, ref i);
|
|
case 12: return new ObjectUpdatePacket(header, bytes, ref i);
|
|
case 13: return new ObjectUpdateCompressedPacket(header, bytes, ref i);
|
|
case 14: return new ObjectUpdateCachedPacket(header, bytes, ref i);
|
|
case 15: return new ImprovedTerseObjectUpdatePacket(header, bytes, ref i);
|
|
case 16: return new KillObjectPacket(header, bytes, ref i);
|
|
case 17: return new TransferPacketPacket(header, bytes, ref i);
|
|
case 18: return new SendXferPacketPacket(header, bytes, ref i);
|
|
case 19: return new ConfirmXferPacketPacket(header, bytes, ref i);
|
|
case 20: return new AvatarAnimationPacket(header, bytes, ref i);
|
|
case 21: return new AvatarSitResponsePacket(header, bytes, ref i);
|
|
case 22: return new CameraConstraintPacket(header, bytes, ref i);
|
|
case 23: return new ParcelPropertiesPacket(header, bytes, ref i);
|
|
case 25: return new ChildAgentUpdatePacket(header, bytes, ref i);
|
|
case 26: return new ChildAgentAlivePacket(header, bytes, ref i);
|
|
case 27: return new ChildAgentPositionUpdatePacket(header, bytes, ref i);
|
|
case 29: return new SoundTriggerPacket(header, bytes, ref i);
|
|
case 30: return new ObjectAnimationPacket(header, bytes, ref i);
|
|
case 31: return new GenericStreamingMessagePacket(header, bytes, ref i);
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
throw new MalformedDataException("Unknown packet ID " + header.Frequency + " " + header.ID);
|
|
}
|
|
}
|
|
/// <exclude/>
|
|
public sealed class TestMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class TestBlock1Block : PacketBlock
|
|
{
|
|
public uint Test1;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public TestBlock1Block() { }
|
|
public TestBlock1Block(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Test1 = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Test1, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class NeighborBlockBlock : PacketBlock
|
|
{
|
|
public uint Test0;
|
|
public uint Test1;
|
|
public uint Test2;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public NeighborBlockBlock() { }
|
|
public NeighborBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Test0 = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Test1 = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Test2 = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Test0, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Test1, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Test2, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += TestBlock1.Length;
|
|
for (int j = 0; j < 4; j++)
|
|
length += NeighborBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TestBlock1Block TestBlock1;
|
|
public NeighborBlockBlock[] NeighborBlock;
|
|
|
|
public TestMessagePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TestMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 1;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
TestBlock1 = new TestBlock1Block();
|
|
NeighborBlock = new NeighborBlockBlock[4];
|
|
}
|
|
|
|
public TestMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TestBlock1.FromBytes(bytes, ref i);
|
|
if(NeighborBlock == null || NeighborBlock.Length != 4) {
|
|
NeighborBlock = new NeighborBlockBlock[4];
|
|
for(int j = 0; j < 4; j++)
|
|
{ NeighborBlock[j] = new NeighborBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < 4; j++)
|
|
{ NeighborBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public TestMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TestBlock1.FromBytes(bytes, ref i);
|
|
if(NeighborBlock == null || NeighborBlock.Length != 4) {
|
|
NeighborBlock = new NeighborBlockBlock[4];
|
|
for(int j = 0; j < 4; j++)
|
|
{ NeighborBlock[j] = new NeighborBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < 4; j++)
|
|
{ NeighborBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TestBlock1.Length;
|
|
for (int j = 0; j < 4; j++) { length += NeighborBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TestBlock1.ToBytes(bytes, ref i);
|
|
for (int j = 0; j < 4; j++) { NeighborBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UseCircuitCodePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class CircuitCodeBlock : PacketBlock
|
|
{
|
|
public uint Code;
|
|
public UUID SessionID;
|
|
public UUID ID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public CircuitCodeBlock() { }
|
|
public CircuitCodeBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Code = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Code, bytes, i); i += 4;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += CircuitCode.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public CircuitCodeBlock CircuitCode;
|
|
|
|
public UseCircuitCodePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.UseCircuitCode;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 3;
|
|
Header.Reliable = true;
|
|
CircuitCode = new CircuitCodeBlock();
|
|
}
|
|
|
|
public UseCircuitCodePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
CircuitCode.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public UseCircuitCodePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
CircuitCode.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += CircuitCode.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
CircuitCode.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TelehubInfoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class TelehubBlockBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public byte[] ObjectName;
|
|
public Vector3 TelehubPos;
|
|
public Quaternion TelehubRot;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 41;
|
|
if (ObjectName != null) { length += ObjectName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public TelehubBlockBlock() { }
|
|
public TelehubBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
ObjectName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ObjectName, 0, length); i += length;
|
|
TelehubPos.FromBytes(bytes, i); i += 12;
|
|
TelehubRot.FromBytes(bytes, i, true); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)ObjectName.Length;
|
|
Buffer.BlockCopy(ObjectName, 0, bytes, i, ObjectName.Length); i += ObjectName.Length;
|
|
TelehubPos.ToBytes(bytes, i); i += 12;
|
|
TelehubRot.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SpawnPointBlockBlock : PacketBlock
|
|
{
|
|
public Vector3 SpawnPointPos;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public SpawnPointBlockBlock() { }
|
|
public SpawnPointBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
SpawnPointPos.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
SpawnPointPos.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += TelehubBlock.Length;
|
|
for (int j = 0; j < SpawnPointBlock.Length; j++)
|
|
length += SpawnPointBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TelehubBlockBlock TelehubBlock;
|
|
public SpawnPointBlockBlock[] SpawnPointBlock;
|
|
|
|
public TelehubInfoPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.TelehubInfo;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 10;
|
|
Header.Reliable = true;
|
|
TelehubBlock = new TelehubBlockBlock();
|
|
SpawnPointBlock = null;
|
|
}
|
|
|
|
public TelehubInfoPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TelehubBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(SpawnPointBlock == null || SpawnPointBlock.Length != -1) {
|
|
SpawnPointBlock = new SpawnPointBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ SpawnPointBlock[j] = new SpawnPointBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ SpawnPointBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public TelehubInfoPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TelehubBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(SpawnPointBlock == null || SpawnPointBlock.Length != count) {
|
|
SpawnPointBlock = new SpawnPointBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ SpawnPointBlock[j] = new SpawnPointBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ SpawnPointBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TelehubBlock.Length;
|
|
length++;
|
|
for (int j = 0; j < SpawnPointBlock.Length; j++) { length += SpawnPointBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TelehubBlock.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)SpawnPointBlock.Length;
|
|
for (int j = 0; j < SpawnPointBlock.Length; j++) { SpawnPointBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += TelehubBlock.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
TelehubBlock.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int SpawnPointBlockStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int SpawnPointBlockCount = 0;
|
|
|
|
i = SpawnPointBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < SpawnPointBlock.Length) {
|
|
int blockLength = SpawnPointBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == SpawnPointBlockStart) {
|
|
variableLength += blockLength;
|
|
++SpawnPointBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)SpawnPointBlockCount;
|
|
for (i = SpawnPointBlockStart; i < SpawnPointBlockStart + SpawnPointBlockCount; i++) { SpawnPointBlock[i].ToBytes(packet, ref length); }
|
|
SpawnPointBlockStart += SpawnPointBlockCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
SpawnPointBlockStart < SpawnPointBlock.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EconomyDataRequestPacket : Packet
|
|
{
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public EconomyDataRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EconomyDataRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 24;
|
|
Header.Reliable = true;
|
|
}
|
|
|
|
public EconomyDataRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
}
|
|
|
|
public EconomyDataRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EconomyDataPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public int ObjectCapacity;
|
|
public int ObjectCount;
|
|
public int PriceEnergyUnit;
|
|
public int PriceObjectClaim;
|
|
public int PricePublicObjectDecay;
|
|
public int PricePublicObjectDelete;
|
|
public int PriceParcelClaim;
|
|
public float PriceParcelClaimFactor;
|
|
public int PriceUpload;
|
|
public int PriceRentLight;
|
|
public int TeleportMinPrice;
|
|
public float TeleportPriceExponent;
|
|
public float EnergyEfficiency;
|
|
public float PriceObjectRent;
|
|
public float PriceObjectScaleFactor;
|
|
public int PriceParcelRent;
|
|
public int PriceGroupCreate;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 68;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectCapacity = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ObjectCount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PriceEnergyUnit = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PriceObjectClaim = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PricePublicObjectDecay = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PricePublicObjectDelete = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PriceParcelClaim = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PriceParcelClaimFactor = Utils.BytesToFloat(bytes, i); i += 4;
|
|
PriceUpload = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PriceRentLight = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TeleportMinPrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TeleportPriceExponent = Utils.BytesToFloat(bytes, i); i += 4;
|
|
EnergyEfficiency = Utils.BytesToFloat(bytes, i); i += 4;
|
|
PriceObjectRent = Utils.BytesToFloat(bytes, i); i += 4;
|
|
PriceObjectScaleFactor = Utils.BytesToFloat(bytes, i); i += 4;
|
|
PriceParcelRent = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PriceGroupCreate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(ObjectCapacity, bytes, i); i += 4;
|
|
Utils.IntToBytes(ObjectCount, bytes, i); i += 4;
|
|
Utils.IntToBytes(PriceEnergyUnit, bytes, i); i += 4;
|
|
Utils.IntToBytes(PriceObjectClaim, bytes, i); i += 4;
|
|
Utils.IntToBytes(PricePublicObjectDecay, bytes, i); i += 4;
|
|
Utils.IntToBytes(PricePublicObjectDelete, bytes, i); i += 4;
|
|
Utils.IntToBytes(PriceParcelClaim, bytes, i); i += 4;
|
|
Utils.FloatToBytes(PriceParcelClaimFactor, bytes, i); i += 4;
|
|
Utils.IntToBytes(PriceUpload, bytes, i); i += 4;
|
|
Utils.IntToBytes(PriceRentLight, bytes, i); i += 4;
|
|
Utils.IntToBytes(TeleportMinPrice, bytes, i); i += 4;
|
|
Utils.FloatToBytes(TeleportPriceExponent, bytes, i); i += 4;
|
|
Utils.FloatToBytes(EnergyEfficiency, bytes, i); i += 4;
|
|
Utils.FloatToBytes(PriceObjectRent, bytes, i); i += 4;
|
|
Utils.FloatToBytes(PriceObjectScaleFactor, bytes, i); i += 4;
|
|
Utils.IntToBytes(PriceParcelRent, bytes, i); i += 4;
|
|
Utils.IntToBytes(PriceGroupCreate, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public InfoBlock Info;
|
|
|
|
public EconomyDataPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EconomyData;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 25;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public EconomyDataPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EconomyDataPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarPickerRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public byte[] Name;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public AvatarPickerRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AvatarPickerRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 26;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public AvatarPickerRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AvatarPickerRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarPickerReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID AvatarID;
|
|
public byte[] FirstName;
|
|
public byte[] LastName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 18;
|
|
if (FirstName != null) { length += FirstName.Length; }
|
|
if (LastName != null) { length += LastName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AvatarID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
FirstName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, FirstName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
LastName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, LastName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AvatarID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)FirstName.Length;
|
|
Buffer.BlockCopy(FirstName, 0, bytes, i, FirstName.Length); i += FirstName.Length;
|
|
bytes[i++] = (byte)LastName.Length;
|
|
Buffer.BlockCopy(LastName, 0, bytes, i, LastName.Length); i += LastName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock[] Data;
|
|
|
|
public AvatarPickerReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AvatarPickerReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 28;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = null;
|
|
}
|
|
|
|
public AvatarPickerReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AvatarPickerReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PlacesQueryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionDataBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TransactionDataBlock() { }
|
|
public TransactionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public byte[] QueryText;
|
|
public uint QueryFlags;
|
|
public sbyte Category;
|
|
public byte[] SimName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
if (QueryText != null) { length += QueryText.Length; }
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
QueryText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, QueryText, 0, length); i += length;
|
|
QueryFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Category = (sbyte)bytes[i++];
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)QueryText.Length;
|
|
Buffer.BlockCopy(QueryText, 0, bytes, i, QueryText.Length); i += QueryText.Length;
|
|
Utils.UIntToBytes(QueryFlags, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Category;
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionData.Length;
|
|
length += QueryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public TransactionDataBlock TransactionData;
|
|
public QueryDataBlock QueryData;
|
|
|
|
public PlacesQueryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.PlacesQuery;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 29;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
TransactionData = new TransactionDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
}
|
|
|
|
public PlacesQueryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public PlacesQueryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionData.Length;
|
|
length += QueryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TransactionData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PlacesReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionDataBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TransactionDataBlock() { }
|
|
public TransactionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID OwnerID;
|
|
public byte[] Name;
|
|
public byte[] Desc;
|
|
public int ActualArea;
|
|
public int BillableArea;
|
|
public byte Flags;
|
|
public float GlobalX;
|
|
public float GlobalY;
|
|
public float GlobalZ;
|
|
public byte[] SimName;
|
|
public UUID SnapshotID;
|
|
public float Dwell;
|
|
public int Price;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 64;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Desc != null) { length += Desc.Length; }
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length;
|
|
ActualArea = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
BillableArea = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Flags = (byte)bytes[i++];
|
|
GlobalX = Utils.BytesToFloat(bytes, i); i += 4;
|
|
GlobalY = Utils.BytesToFloat(bytes, i); i += 4;
|
|
GlobalZ = Utils.BytesToFloat(bytes, i); i += 4;
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
SnapshotID.FromBytes(bytes, i); i += 16;
|
|
Dwell = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Price = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Desc.Length;
|
|
Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length;
|
|
Utils.IntToBytes(ActualArea, bytes, i); i += 4;
|
|
Utils.IntToBytes(BillableArea, bytes, i); i += 4;
|
|
bytes[i++] = Flags;
|
|
Utils.FloatToBytes(GlobalX, bytes, i); i += 4;
|
|
Utils.FloatToBytes(GlobalY, bytes, i); i += 4;
|
|
Utils.FloatToBytes(GlobalZ, bytes, i); i += 4;
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
SnapshotID.ToBytes(bytes, i); i += 16;
|
|
Utils.FloatToBytes(Dwell, bytes, i); i += 4;
|
|
Utils.IntToBytes(Price, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += TransactionData.Length;
|
|
for (int j = 0; j < QueryData.Length; j++)
|
|
length += QueryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public TransactionDataBlock TransactionData;
|
|
public QueryDataBlock[] QueryData;
|
|
|
|
public PlacesReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.PlacesReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 30;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
TransactionData = new TransactionDataBlock();
|
|
QueryData = null;
|
|
}
|
|
|
|
public PlacesReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryData == null || QueryData.Length != -1) {
|
|
QueryData = new QueryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryData[j] = new QueryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public PlacesReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryData == null || QueryData.Length != count) {
|
|
QueryData = new QueryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryData[j] = new QueryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionData.Length;
|
|
length++;
|
|
for (int j = 0; j < QueryData.Length; j++) { length += QueryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TransactionData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)QueryData.Length;
|
|
for (int j = 0; j < QueryData.Length; j++) { QueryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += TransactionData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
TransactionData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int QueryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int QueryDataCount = 0;
|
|
|
|
i = QueryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < QueryData.Length) {
|
|
int blockLength = QueryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == QueryDataStart) {
|
|
variableLength += blockLength;
|
|
++QueryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)QueryDataCount;
|
|
for (i = QueryDataStart; i < QueryDataStart + QueryDataCount; i++) { QueryData[i].ToBytes(packet, ref length); }
|
|
QueryDataStart += QueryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
QueryDataStart < QueryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirFindQueryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
public byte[] QueryText;
|
|
public uint QueryFlags;
|
|
public int QueryStart;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 25;
|
|
if (QueryText != null) { length += QueryText.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
QueryText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, QueryText, 0, length); i += length;
|
|
QueryFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
QueryStart = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)QueryText.Length;
|
|
Buffer.BlockCopy(QueryText, 0, bytes, i, QueryText.Length); i += QueryText.Length;
|
|
Utils.UIntToBytes(QueryFlags, bytes, i); i += 4;
|
|
Utils.IntToBytes(QueryStart, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
|
|
public DirFindQueryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DirFindQuery;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 31;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
}
|
|
|
|
public DirFindQueryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public DirFindQueryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirPlacesQueryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
public byte[] QueryText;
|
|
public uint QueryFlags;
|
|
public sbyte Category;
|
|
public byte[] SimName;
|
|
public int QueryStart;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 27;
|
|
if (QueryText != null) { length += QueryText.Length; }
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
QueryText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, QueryText, 0, length); i += length;
|
|
QueryFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Category = (sbyte)bytes[i++];
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
QueryStart = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)QueryText.Length;
|
|
Buffer.BlockCopy(QueryText, 0, bytes, i, QueryText.Length); i += QueryText.Length;
|
|
Utils.UIntToBytes(QueryFlags, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Category;
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
Utils.IntToBytes(QueryStart, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
|
|
public DirPlacesQueryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DirPlacesQuery;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 33;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
}
|
|
|
|
public DirPlacesQueryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public DirPlacesQueryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirPlacesReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID ParcelID;
|
|
public byte[] Name;
|
|
public bool ForSale;
|
|
public bool Auction;
|
|
public float Dwell;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 23;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryRepliesBlock() { }
|
|
public QueryRepliesBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
ForSale = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Auction = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Dwell = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)((ForSale) ? 1 : 0);
|
|
bytes[i++] = (byte)((Auction) ? 1 : 0);
|
|
Utils.FloatToBytes(Dwell, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StatusDataBlock : PacketBlock
|
|
{
|
|
public uint Status;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public StatusDataBlock() { }
|
|
public StatusDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Status = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Status, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 13;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < QueryData.Length; j++)
|
|
length += QueryData[j].Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++)
|
|
length += QueryReplies[j].Length;
|
|
for (int j = 0; j < StatusData.Length; j++)
|
|
length += StatusData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock[] QueryData;
|
|
public QueryRepliesBlock[] QueryReplies;
|
|
public StatusDataBlock[] StatusData;
|
|
|
|
public DirPlacesReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.DirPlacesReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 35;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = null;
|
|
QueryReplies = null;
|
|
StatusData = null;
|
|
}
|
|
|
|
public DirPlacesReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryData == null || QueryData.Length != -1) {
|
|
QueryData = new QueryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryData[j] = new QueryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != -1) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(StatusData == null || StatusData.Length != -1) {
|
|
StatusData = new StatusDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ StatusData[j] = new StatusDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ StatusData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public DirPlacesReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryData == null || QueryData.Length != count) {
|
|
QueryData = new QueryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryData[j] = new QueryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != count) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(StatusData == null || StatusData.Length != count) {
|
|
StatusData = new StatusDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ StatusData[j] = new StatusDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ StatusData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < QueryData.Length; j++) { length += QueryData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { length += QueryReplies[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < StatusData.Length; j++) { length += StatusData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)QueryData.Length;
|
|
for (int j = 0; j < QueryData.Length; j++) { QueryData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)QueryReplies.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)StatusData.Length;
|
|
for (int j = 0; j < StatusData.Length; j++) { StatusData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 3;
|
|
|
|
int QueryDataStart = 0;
|
|
int QueryRepliesStart = 0;
|
|
int StatusDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int QueryDataCount = 0;
|
|
int QueryRepliesCount = 0;
|
|
int StatusDataCount = 0;
|
|
|
|
i = QueryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < QueryData.Length) {
|
|
int blockLength = QueryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == QueryDataStart) {
|
|
variableLength += blockLength;
|
|
++QueryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = QueryRepliesStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < QueryReplies.Length) {
|
|
int blockLength = QueryReplies[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == QueryRepliesStart) {
|
|
variableLength += blockLength;
|
|
++QueryRepliesCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = StatusDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < StatusData.Length) {
|
|
int blockLength = StatusData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == StatusDataStart) {
|
|
variableLength += blockLength;
|
|
++StatusDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)QueryDataCount;
|
|
for (i = QueryDataStart; i < QueryDataStart + QueryDataCount; i++) { QueryData[i].ToBytes(packet, ref length); }
|
|
QueryDataStart += QueryDataCount;
|
|
|
|
packet[length++] = (byte)QueryRepliesCount;
|
|
for (i = QueryRepliesStart; i < QueryRepliesStart + QueryRepliesCount; i++) { QueryReplies[i].ToBytes(packet, ref length); }
|
|
QueryRepliesStart += QueryRepliesCount;
|
|
|
|
packet[length++] = (byte)StatusDataCount;
|
|
for (i = StatusDataStart; i < StatusDataStart + StatusDataCount; i++) { StatusData[i].ToBytes(packet, ref length); }
|
|
StatusDataStart += StatusDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
QueryDataStart < QueryData.Length ||
|
|
QueryRepliesStart < QueryReplies.Length ||
|
|
StatusDataStart < StatusData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirPeopleReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public byte[] FirstName;
|
|
public byte[] LastName;
|
|
public byte[] Group;
|
|
public bool Online;
|
|
public int Reputation;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 24;
|
|
if (FirstName != null) { length += FirstName.Length; }
|
|
if (LastName != null) { length += LastName.Length; }
|
|
if (Group != null) { length += Group.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryRepliesBlock() { }
|
|
public QueryRepliesBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
FirstName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, FirstName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
LastName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, LastName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Group = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Group, 0, length); i += length;
|
|
Online = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Reputation = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)FirstName.Length;
|
|
Buffer.BlockCopy(FirstName, 0, bytes, i, FirstName.Length); i += FirstName.Length;
|
|
bytes[i++] = (byte)LastName.Length;
|
|
Buffer.BlockCopy(LastName, 0, bytes, i, LastName.Length); i += LastName.Length;
|
|
bytes[i++] = (byte)Group.Length;
|
|
Buffer.BlockCopy(Group, 0, bytes, i, Group.Length); i += Group.Length;
|
|
bytes[i++] = (byte)((Online) ? 1 : 0);
|
|
Utils.IntToBytes(Reputation, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++)
|
|
length += QueryReplies[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
public QueryRepliesBlock[] QueryReplies;
|
|
|
|
public DirPeopleReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.DirPeopleReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 36;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
QueryReplies = null;
|
|
}
|
|
|
|
public DirPeopleReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != -1) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public DirPeopleReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != count) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
length++;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { length += QueryReplies[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)QueryReplies.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += QueryData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
QueryData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int QueryRepliesStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int QueryRepliesCount = 0;
|
|
|
|
i = QueryRepliesStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < QueryReplies.Length) {
|
|
int blockLength = QueryReplies[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == QueryRepliesStart) {
|
|
variableLength += blockLength;
|
|
++QueryRepliesCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)QueryRepliesCount;
|
|
for (i = QueryRepliesStart; i < QueryRepliesStart + QueryRepliesCount; i++) { QueryReplies[i].ToBytes(packet, ref length); }
|
|
QueryRepliesStart += QueryRepliesCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
QueryRepliesStart < QueryReplies.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirEventsReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID OwnerID;
|
|
public byte[] Name;
|
|
public uint EventID;
|
|
public byte[] Date;
|
|
public uint UnixTime;
|
|
public uint EventFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 30;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Date != null) { length += Date.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryRepliesBlock() { }
|
|
public QueryRepliesBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
EventID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Date = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Date, 0, length); i += length;
|
|
UnixTime = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EventFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
Utils.UIntToBytes(EventID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Date.Length;
|
|
Buffer.BlockCopy(Date, 0, bytes, i, Date.Length); i += Date.Length;
|
|
Utils.UIntToBytes(UnixTime, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EventFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StatusDataBlock : PacketBlock
|
|
{
|
|
public uint Status;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public StatusDataBlock() { }
|
|
public StatusDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Status = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Status, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++)
|
|
length += QueryReplies[j].Length;
|
|
for (int j = 0; j < StatusData.Length; j++)
|
|
length += StatusData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
public QueryRepliesBlock[] QueryReplies;
|
|
public StatusDataBlock[] StatusData;
|
|
|
|
public DirEventsReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.DirEventsReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 37;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
QueryReplies = null;
|
|
StatusData = null;
|
|
}
|
|
|
|
public DirEventsReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != -1) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(StatusData == null || StatusData.Length != -1) {
|
|
StatusData = new StatusDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ StatusData[j] = new StatusDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ StatusData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public DirEventsReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != count) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(StatusData == null || StatusData.Length != count) {
|
|
StatusData = new StatusDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ StatusData[j] = new StatusDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ StatusData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
length++;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { length += QueryReplies[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < StatusData.Length; j++) { length += StatusData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)QueryReplies.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)StatusData.Length;
|
|
for (int j = 0; j < StatusData.Length; j++) { StatusData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += QueryData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
QueryData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int QueryRepliesStart = 0;
|
|
int StatusDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int QueryRepliesCount = 0;
|
|
int StatusDataCount = 0;
|
|
|
|
i = QueryRepliesStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < QueryReplies.Length) {
|
|
int blockLength = QueryReplies[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == QueryRepliesStart) {
|
|
variableLength += blockLength;
|
|
++QueryRepliesCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = StatusDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < StatusData.Length) {
|
|
int blockLength = StatusData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == StatusDataStart) {
|
|
variableLength += blockLength;
|
|
++StatusDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)QueryRepliesCount;
|
|
for (i = QueryRepliesStart; i < QueryRepliesStart + QueryRepliesCount; i++) { QueryReplies[i].ToBytes(packet, ref length); }
|
|
QueryRepliesStart += QueryRepliesCount;
|
|
|
|
packet[length++] = (byte)StatusDataCount;
|
|
for (i = StatusDataStart; i < StatusDataStart + StatusDataCount; i++) { StatusData[i].ToBytes(packet, ref length); }
|
|
StatusDataStart += StatusDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
QueryRepliesStart < QueryReplies.Length ||
|
|
StatusDataStart < StatusData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirGroupsReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public byte[] GroupName;
|
|
public int Members;
|
|
public float SearchOrder;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 25;
|
|
if (GroupName != null) { length += GroupName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryRepliesBlock() { }
|
|
public QueryRepliesBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
GroupName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, GroupName, 0, length); i += length;
|
|
Members = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SearchOrder = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)GroupName.Length;
|
|
Buffer.BlockCopy(GroupName, 0, bytes, i, GroupName.Length); i += GroupName.Length;
|
|
Utils.IntToBytes(Members, bytes, i); i += 4;
|
|
Utils.FloatToBytes(SearchOrder, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++)
|
|
length += QueryReplies[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
public QueryRepliesBlock[] QueryReplies;
|
|
|
|
public DirGroupsReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.DirGroupsReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 38;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
QueryReplies = null;
|
|
}
|
|
|
|
public DirGroupsReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != -1) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public DirGroupsReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != count) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
length++;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { length += QueryReplies[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)QueryReplies.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += QueryData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
QueryData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int QueryRepliesStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int QueryRepliesCount = 0;
|
|
|
|
i = QueryRepliesStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < QueryReplies.Length) {
|
|
int blockLength = QueryReplies[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == QueryRepliesStart) {
|
|
variableLength += blockLength;
|
|
++QueryRepliesCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)QueryRepliesCount;
|
|
for (i = QueryRepliesStart; i < QueryRepliesStart + QueryRepliesCount; i++) { QueryReplies[i].ToBytes(packet, ref length); }
|
|
QueryRepliesStart += QueryRepliesCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
QueryRepliesStart < QueryReplies.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirClassifiedQueryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
public byte[] QueryText;
|
|
public uint QueryFlags;
|
|
public uint Category;
|
|
public int QueryStart;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 29;
|
|
if (QueryText != null) { length += QueryText.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
QueryText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, QueryText, 0, length); i += length;
|
|
QueryFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Category = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
QueryStart = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)QueryText.Length;
|
|
Buffer.BlockCopy(QueryText, 0, bytes, i, QueryText.Length); i += QueryText.Length;
|
|
Utils.UIntToBytes(QueryFlags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Category, bytes, i); i += 4;
|
|
Utils.IntToBytes(QueryStart, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
|
|
public DirClassifiedQueryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DirClassifiedQuery;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 39;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
}
|
|
|
|
public DirClassifiedQueryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public DirClassifiedQueryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirClassifiedReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
public byte[] Name;
|
|
public byte ClassifiedFlags;
|
|
public uint CreationDate;
|
|
public uint ExpirationDate;
|
|
public int PriceForListing;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 30;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryRepliesBlock() { }
|
|
public QueryRepliesBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ClassifiedID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
ClassifiedFlags = (byte)bytes[i++];
|
|
CreationDate = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ExpirationDate = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PriceForListing = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ClassifiedID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = ClassifiedFlags;
|
|
Utils.UIntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ExpirationDate, bytes, i); i += 4;
|
|
Utils.IntToBytes(PriceForListing, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StatusDataBlock : PacketBlock
|
|
{
|
|
public uint Status;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public StatusDataBlock() { }
|
|
public StatusDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Status = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Status, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++)
|
|
length += QueryReplies[j].Length;
|
|
for (int j = 0; j < StatusData.Length; j++)
|
|
length += StatusData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
public QueryRepliesBlock[] QueryReplies;
|
|
public StatusDataBlock[] StatusData;
|
|
|
|
public DirClassifiedReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.DirClassifiedReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 41;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
QueryReplies = null;
|
|
StatusData = null;
|
|
}
|
|
|
|
public DirClassifiedReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != -1) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(StatusData == null || StatusData.Length != -1) {
|
|
StatusData = new StatusDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ StatusData[j] = new StatusDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ StatusData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public DirClassifiedReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != count) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(StatusData == null || StatusData.Length != count) {
|
|
StatusData = new StatusDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ StatusData[j] = new StatusDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ StatusData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
length++;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { length += QueryReplies[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < StatusData.Length; j++) { length += StatusData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)QueryReplies.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)StatusData.Length;
|
|
for (int j = 0; j < StatusData.Length; j++) { StatusData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += QueryData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
QueryData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int QueryRepliesStart = 0;
|
|
int StatusDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int QueryRepliesCount = 0;
|
|
int StatusDataCount = 0;
|
|
|
|
i = QueryRepliesStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < QueryReplies.Length) {
|
|
int blockLength = QueryReplies[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == QueryRepliesStart) {
|
|
variableLength += blockLength;
|
|
++QueryRepliesCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = StatusDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < StatusData.Length) {
|
|
int blockLength = StatusData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == StatusDataStart) {
|
|
variableLength += blockLength;
|
|
++StatusDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)QueryRepliesCount;
|
|
for (i = QueryRepliesStart; i < QueryRepliesStart + QueryRepliesCount; i++) { QueryReplies[i].ToBytes(packet, ref length); }
|
|
QueryRepliesStart += QueryRepliesCount;
|
|
|
|
packet[length++] = (byte)StatusDataCount;
|
|
for (i = StatusDataStart; i < StatusDataStart + StatusDataCount; i++) { StatusData[i].ToBytes(packet, ref length); }
|
|
StatusDataStart += StatusDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
QueryRepliesStart < QueryReplies.Length ||
|
|
StatusDataStart < StatusData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarClassifiedReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID TargetID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
TargetID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
TargetID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
public byte[] Name;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ClassifiedID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ClassifiedID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock[] Data;
|
|
|
|
public AvatarClassifiedReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AvatarClassifiedReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 42;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = null;
|
|
}
|
|
|
|
public AvatarClassifiedReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AvatarClassifiedReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ClassifiedInfoRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ClassifiedID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ClassifiedID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ClassifiedInfoRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ClassifiedInfoRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 43;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ClassifiedInfoRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ClassifiedInfoRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ClassifiedInfoReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
public UUID CreatorID;
|
|
public uint CreationDate;
|
|
public uint ExpirationDate;
|
|
public uint Category;
|
|
public byte[] Name;
|
|
public byte[] Desc;
|
|
public UUID ParcelID;
|
|
public uint ParentEstate;
|
|
public UUID SnapshotID;
|
|
public byte[] SimName;
|
|
public Vector3d PosGlobal;
|
|
public byte[] ParcelName;
|
|
public byte ClassifiedFlags;
|
|
public int PriceForListing;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 114;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Desc != null) { length += Desc.Length; }
|
|
if (SimName != null) { length += SimName.Length; }
|
|
if (ParcelName != null) { length += ParcelName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ClassifiedID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
CreationDate = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ExpirationDate = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Category = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length;
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
ParentEstate = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SnapshotID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
PosGlobal.FromBytes(bytes, i); i += 24;
|
|
length = bytes[i++];
|
|
ParcelName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ParcelName, 0, length); i += length;
|
|
ClassifiedFlags = (byte)bytes[i++];
|
|
PriceForListing = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ClassifiedID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ExpirationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Category, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)(Desc.Length % 256);
|
|
bytes[i++] = (byte)((Desc.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length;
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(ParentEstate, bytes, i); i += 4;
|
|
SnapshotID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
PosGlobal.ToBytes(bytes, i); i += 24;
|
|
bytes[i++] = (byte)ParcelName.Length;
|
|
Buffer.BlockCopy(ParcelName, 0, bytes, i, ParcelName.Length); i += ParcelName.Length;
|
|
bytes[i++] = ClassifiedFlags;
|
|
Utils.IntToBytes(PriceForListing, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ClassifiedInfoReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ClassifiedInfoReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 44;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ClassifiedInfoReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ClassifiedInfoReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ClassifiedInfoUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
public uint Category;
|
|
public byte[] Name;
|
|
public byte[] Desc;
|
|
public UUID ParcelID;
|
|
public uint ParentEstate;
|
|
public UUID SnapshotID;
|
|
public Vector3d PosGlobal;
|
|
public byte ClassifiedFlags;
|
|
public int PriceForListing;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 88;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Desc != null) { length += Desc.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ClassifiedID.FromBytes(bytes, i); i += 16;
|
|
Category = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length;
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
ParentEstate = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SnapshotID.FromBytes(bytes, i); i += 16;
|
|
PosGlobal.FromBytes(bytes, i); i += 24;
|
|
ClassifiedFlags = (byte)bytes[i++];
|
|
PriceForListing = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ClassifiedID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Category, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)(Desc.Length % 256);
|
|
bytes[i++] = (byte)((Desc.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length;
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(ParentEstate, bytes, i); i += 4;
|
|
SnapshotID.ToBytes(bytes, i); i += 16;
|
|
PosGlobal.ToBytes(bytes, i); i += 24;
|
|
bytes[i++] = ClassifiedFlags;
|
|
Utils.IntToBytes(PriceForListing, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ClassifiedInfoUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ClassifiedInfoUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 45;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ClassifiedInfoUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ClassifiedInfoUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ClassifiedDeletePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ClassifiedID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ClassifiedID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ClassifiedDeletePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ClassifiedDelete;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 46;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ClassifiedDeletePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ClassifiedDeletePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ClassifiedGodDeletePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ClassifiedID.FromBytes(bytes, i); i += 16;
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ClassifiedID.ToBytes(bytes, i); i += 16;
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ClassifiedGodDeletePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ClassifiedGodDelete;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 47;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ClassifiedGodDeletePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ClassifiedGodDeletePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirLandQueryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
public uint QueryFlags;
|
|
public uint SearchType;
|
|
public int Price;
|
|
public int Area;
|
|
public int QueryStart;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
QueryFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SearchType = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Price = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Area = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
QueryStart = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(QueryFlags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(SearchType, bytes, i); i += 4;
|
|
Utils.IntToBytes(Price, bytes, i); i += 4;
|
|
Utils.IntToBytes(Area, bytes, i); i += 4;
|
|
Utils.IntToBytes(QueryStart, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
|
|
public DirLandQueryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DirLandQuery;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 48;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
}
|
|
|
|
public DirLandQueryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public DirLandQueryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirLandReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID ParcelID;
|
|
public byte[] Name;
|
|
public bool Auction;
|
|
public bool ForSale;
|
|
public int SalePrice;
|
|
public int ActualArea;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 27;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryRepliesBlock() { }
|
|
public QueryRepliesBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
Auction = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
ForSale = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ActualArea = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)((Auction) ? 1 : 0);
|
|
bytes[i++] = (byte)((ForSale) ? 1 : 0);
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
Utils.IntToBytes(ActualArea, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++)
|
|
length += QueryReplies[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
public QueryRepliesBlock[] QueryReplies;
|
|
|
|
public DirLandReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.DirLandReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 50;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
QueryReplies = null;
|
|
}
|
|
|
|
public DirLandReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != -1) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public DirLandReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != count) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
length++;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { length += QueryReplies[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)QueryReplies.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += QueryData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
QueryData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int QueryRepliesStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int QueryRepliesCount = 0;
|
|
|
|
i = QueryRepliesStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < QueryReplies.Length) {
|
|
int blockLength = QueryReplies[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == QueryRepliesStart) {
|
|
variableLength += blockLength;
|
|
++QueryRepliesCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)QueryRepliesCount;
|
|
for (i = QueryRepliesStart; i < QueryRepliesStart + QueryRepliesCount; i++) { QueryReplies[i].ToBytes(packet, ref length); }
|
|
QueryRepliesStart += QueryRepliesCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
QueryRepliesStart < QueryReplies.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirPopularQueryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
public uint QueryFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
QueryFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(QueryFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
|
|
public DirPopularQueryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DirPopularQuery;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 51;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
}
|
|
|
|
public DirPopularQueryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public DirPopularQueryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirPopularReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID ParcelID;
|
|
public byte[] Name;
|
|
public float Dwell;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 21;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryRepliesBlock() { }
|
|
public QueryRepliesBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
Dwell = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
Utils.FloatToBytes(Dwell, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++)
|
|
length += QueryReplies[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public QueryDataBlock QueryData;
|
|
public QueryRepliesBlock[] QueryReplies;
|
|
|
|
public DirPopularReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.DirPopularReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 53;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
QueryReplies = null;
|
|
}
|
|
|
|
public DirPopularReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != -1) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public DirPopularReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(QueryReplies == null || QueryReplies.Length != count) {
|
|
QueryReplies = new QueryRepliesBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ QueryReplies[j] = new QueryRepliesBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ QueryReplies[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += QueryData.Length;
|
|
length++;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { length += QueryReplies[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)QueryReplies.Length;
|
|
for (int j = 0; j < QueryReplies.Length; j++) { QueryReplies[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += QueryData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
QueryData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int QueryRepliesStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int QueryRepliesCount = 0;
|
|
|
|
i = QueryRepliesStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < QueryReplies.Length) {
|
|
int blockLength = QueryReplies[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == QueryRepliesStart) {
|
|
variableLength += blockLength;
|
|
++QueryRepliesCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)QueryRepliesCount;
|
|
for (i = QueryRepliesStart; i < QueryRepliesStart + QueryRepliesCount; i++) { QueryReplies[i].ToBytes(packet, ref length); }
|
|
QueryRepliesStart += QueryRepliesCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
QueryRepliesStart < QueryReplies.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelInfoRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ParcelID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ParcelInfoRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelInfoRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 54;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ParcelInfoRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelInfoRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelInfoReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ParcelID;
|
|
public UUID OwnerID;
|
|
public byte[] Name;
|
|
public byte[] Desc;
|
|
public int ActualArea;
|
|
public int BillableArea;
|
|
public byte Flags;
|
|
public float GlobalX;
|
|
public float GlobalY;
|
|
public float GlobalZ;
|
|
public byte[] SimName;
|
|
public UUID SnapshotID;
|
|
public float Dwell;
|
|
public int SalePrice;
|
|
public int AuctionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 84;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Desc != null) { length += Desc.Length; }
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length;
|
|
ActualArea = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
BillableArea = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Flags = (byte)bytes[i++];
|
|
GlobalX = Utils.BytesToFloat(bytes, i); i += 4;
|
|
GlobalY = Utils.BytesToFloat(bytes, i); i += 4;
|
|
GlobalZ = Utils.BytesToFloat(bytes, i); i += 4;
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
SnapshotID.FromBytes(bytes, i); i += 16;
|
|
Dwell = Utils.BytesToFloat(bytes, i); i += 4;
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
AuctionID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Desc.Length;
|
|
Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length;
|
|
Utils.IntToBytes(ActualArea, bytes, i); i += 4;
|
|
Utils.IntToBytes(BillableArea, bytes, i); i += 4;
|
|
bytes[i++] = Flags;
|
|
Utils.FloatToBytes(GlobalX, bytes, i); i += 4;
|
|
Utils.FloatToBytes(GlobalY, bytes, i); i += 4;
|
|
Utils.FloatToBytes(GlobalZ, bytes, i); i += 4;
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
SnapshotID.ToBytes(bytes, i); i += 16;
|
|
Utils.FloatToBytes(Dwell, bytes, i); i += 4;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
Utils.IntToBytes(AuctionID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ParcelInfoReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelInfoReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 55;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ParcelInfoReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelInfoReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelObjectOwnersRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelObjectOwnersRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelObjectOwnersRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 56;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelObjectOwnersRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelObjectOwnersRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelObjectOwnersReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID OwnerID;
|
|
public bool IsGroupOwned;
|
|
public int Count;
|
|
public bool OnlineStatus;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 22;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
IsGroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Count = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OnlineStatus = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsGroupOwned) ? 1 : 0);
|
|
Utils.IntToBytes(Count, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((OnlineStatus) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock[] Data;
|
|
|
|
public ParcelObjectOwnersReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ParcelObjectOwnersReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 57;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
Data = null;
|
|
}
|
|
|
|
public ParcelObjectOwnersReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ParcelObjectOwnersReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupNoticesListRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public GroupNoticesListRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupNoticesListRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 58;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public GroupNoticesListRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupNoticesListRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupNoticesListReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID NoticeID;
|
|
public uint Timestamp;
|
|
public byte[] FromName;
|
|
public byte[] Subject;
|
|
public bool HasAttachment;
|
|
public byte AssetType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 26;
|
|
if (FromName != null) { length += FromName.Length; }
|
|
if (Subject != null) { length += Subject.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
NoticeID.FromBytes(bytes, i); i += 16;
|
|
Timestamp = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
FromName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, FromName, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Subject = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Subject, 0, length); i += length;
|
|
HasAttachment = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
AssetType = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
NoticeID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Timestamp, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(FromName.Length % 256);
|
|
bytes[i++] = (byte)((FromName.Length >> 8) % 256);
|
|
Buffer.BlockCopy(FromName, 0, bytes, i, FromName.Length); i += FromName.Length;
|
|
bytes[i++] = (byte)(Subject.Length % 256);
|
|
bytes[i++] = (byte)((Subject.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Subject, 0, bytes, i, Subject.Length); i += Subject.Length;
|
|
bytes[i++] = (byte)((HasAttachment) ? 1 : 0);
|
|
bytes[i++] = AssetType;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock[] Data;
|
|
|
|
public GroupNoticesListReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupNoticesListReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 59;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = null;
|
|
}
|
|
|
|
public GroupNoticesListReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupNoticesListReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupNoticeRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID GroupNoticeID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupNoticeID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupNoticeID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public GroupNoticeRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupNoticeRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 60;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public GroupNoticeRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupNoticeRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public UUID RegionID;
|
|
public Vector3 Position;
|
|
public Vector3 LookAt;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 40;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionID.FromBytes(bytes, i); i += 16;
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
LookAt.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RegionID.ToBytes(bytes, i); i += 16;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
LookAt.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InfoBlock Info;
|
|
|
|
public TeleportRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TeleportRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 62;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public TeleportRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TeleportRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportLocationRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public ulong RegionHandle;
|
|
public Vector3 Position;
|
|
public Vector3 LookAt;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
LookAt.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
LookAt.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InfoBlock Info;
|
|
|
|
public TeleportLocationRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TeleportLocationRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 63;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public TeleportLocationRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TeleportLocationRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportLocalPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public uint LocationID;
|
|
public Vector3 Position;
|
|
public Vector3 LookAt;
|
|
public uint TeleportFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
LocationID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
LookAt.FromBytes(bytes, i); i += 12;
|
|
TeleportFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(LocationID, bytes, i); i += 4;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
LookAt.ToBytes(bytes, i); i += 12;
|
|
Utils.UIntToBytes(TeleportFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public InfoBlock Info;
|
|
|
|
public TeleportLocalPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TeleportLocal;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 64;
|
|
Header.Reliable = true;
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public TeleportLocalPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TeleportLocalPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportLandmarkRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID LandmarkID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
LandmarkID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
LandmarkID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public InfoBlock Info;
|
|
|
|
public TeleportLandmarkRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TeleportLandmarkRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 65;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public TeleportLandmarkRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TeleportLandmarkRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportProgressPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public uint TeleportFlags;
|
|
public byte[] Message;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 5;
|
|
if (Message != null) { length += Message.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TeleportFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(TeleportFlags, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Message.Length;
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InfoBlock Info;
|
|
|
|
public TeleportProgressPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TeleportProgress;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 66;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public TeleportProgressPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TeleportProgressPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportFinishPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public uint LocationID;
|
|
public uint SimIP;
|
|
public ushort SimPort;
|
|
public ulong RegionHandle;
|
|
public byte[] SeedCapability;
|
|
public byte SimAccess;
|
|
public uint TeleportFlags;
|
|
// Sim/region size information sent in TeleportFinishMesssage
|
|
public uint RegionSizeX = Simulator.DefaultRegionSizeX;
|
|
public uint RegionSizeY = Simulator.DefaultRegionSizeY;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 41;
|
|
if (SeedCapability != null) { length += SeedCapability.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
LocationID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SimIP = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SimPort = (ushort)((bytes[i++] << 8) + bytes[i++]);
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
SeedCapability = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SeedCapability, 0, length); i += length;
|
|
SimAccess = (byte)bytes[i++];
|
|
TeleportFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(LocationID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(SimIP, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((SimPort >> 8) % 256);
|
|
bytes[i++] = (byte)(SimPort % 256);
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
bytes[i++] = (byte)(SeedCapability.Length % 256);
|
|
bytes[i++] = (byte)((SeedCapability.Length >> 8) % 256);
|
|
Buffer.BlockCopy(SeedCapability, 0, bytes, i, SeedCapability.Length); i += SeedCapability.Length;
|
|
bytes[i++] = SimAccess;
|
|
Utils.UIntToBytes(TeleportFlags, bytes, i); i += 4;
|
|
// size information is not sent in the UDP packet
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public InfoBlock Info;
|
|
|
|
public TeleportFinishPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TeleportFinish;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 69;
|
|
Header.Reliable = true;
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public TeleportFinishPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TeleportFinishPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StartLurePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public byte LureType;
|
|
public byte[] Message;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (Message != null) { length += Message.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
LureType = (byte)bytes[i++];
|
|
length = bytes[i++];
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = LureType;
|
|
bytes[i++] = (byte)Message.Length;
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TargetDataBlock : PacketBlock
|
|
{
|
|
public UUID TargetID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TargetDataBlock() { }
|
|
public TargetDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TargetID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TargetID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += Info.Length;
|
|
for (int j = 0; j < TargetData.Length; j++)
|
|
length += TargetData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InfoBlock Info;
|
|
public TargetDataBlock[] TargetData;
|
|
|
|
public StartLurePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.StartLure;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 70;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Info = new InfoBlock();
|
|
TargetData = null;
|
|
}
|
|
|
|
public StartLurePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Info.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(TargetData == null || TargetData.Length != -1) {
|
|
TargetData = new TargetDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ TargetData[j] = new TargetDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ TargetData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public StartLurePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Info.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(TargetData == null || TargetData.Length != count) {
|
|
TargetData = new TargetDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ TargetData[j] = new TargetDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ TargetData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Info.Length;
|
|
length++;
|
|
for (int j = 0; j < TargetData.Length; j++) { length += TargetData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)TargetData.Length;
|
|
for (int j = 0; j < TargetData.Length; j++) { TargetData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += Info.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
Info.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int TargetDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int TargetDataCount = 0;
|
|
|
|
i = TargetDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < TargetData.Length) {
|
|
int blockLength = TargetData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == TargetDataStart) {
|
|
variableLength += blockLength;
|
|
++TargetDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)TargetDataCount;
|
|
for (i = TargetDataStart; i < TargetDataStart + TargetDataCount; i++) { TargetData[i].ToBytes(packet, ref length); }
|
|
TargetDataStart += TargetDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
TargetDataStart < TargetData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportLureRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID LureID;
|
|
public uint TeleportFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 52;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
LureID.FromBytes(bytes, i); i += 16;
|
|
TeleportFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
LureID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(TeleportFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public InfoBlock Info;
|
|
|
|
public TeleportLureRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TeleportLureRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 71;
|
|
Header.Reliable = true;
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public TeleportLureRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TeleportLureRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportCancelPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public InfoBlock Info;
|
|
|
|
public TeleportCancelPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TeleportCancel;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 72;
|
|
Header.Reliable = true;
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public TeleportCancelPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TeleportCancelPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportStartPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public uint TeleportFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TeleportFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(TeleportFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public InfoBlock Info;
|
|
|
|
public TeleportStartPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TeleportStart;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 73;
|
|
Header.Reliable = true;
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public TeleportStartPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TeleportStartPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportFailedPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public byte[] Reason;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (Reason != null) { length += Reason.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Reason = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Reason, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Reason.Length;
|
|
Buffer.BlockCopy(Reason, 0, bytes, i, Reason.Length); i += Reason.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AlertInfoBlock : PacketBlock
|
|
{
|
|
public byte[] Message;
|
|
public byte[] ExtraParams;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (Message != null) { length += Message.Length; }
|
|
if (ExtraParams != null) { length += ExtraParams.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AlertInfoBlock() { }
|
|
public AlertInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
length = bytes[i++];
|
|
ExtraParams = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ExtraParams, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Message.Length;
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
bytes[i++] = (byte)ExtraParams.Length;
|
|
Buffer.BlockCopy(ExtraParams, 0, bytes, i, ExtraParams.Length); i += ExtraParams.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += Info.Length;
|
|
for (int j = 0; j < AlertInfo.Length; j++)
|
|
length += AlertInfo[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public InfoBlock Info;
|
|
public AlertInfoBlock[] AlertInfo;
|
|
|
|
public TeleportFailedPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.TeleportFailed;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 74;
|
|
Header.Reliable = true;
|
|
Info = new InfoBlock();
|
|
AlertInfo = null;
|
|
}
|
|
|
|
public TeleportFailedPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Info.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(AlertInfo == null || AlertInfo.Length != -1) {
|
|
AlertInfo = new AlertInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AlertInfo[j] = new AlertInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AlertInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public TeleportFailedPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Info.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(AlertInfo == null || AlertInfo.Length != count) {
|
|
AlertInfo = new AlertInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AlertInfo[j] = new AlertInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AlertInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Info.Length;
|
|
length++;
|
|
for (int j = 0; j < AlertInfo.Length; j++) { length += AlertInfo[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AlertInfo.Length;
|
|
for (int j = 0; j < AlertInfo.Length; j++) { AlertInfo[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += Info.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
Info.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int AlertInfoStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int AlertInfoCount = 0;
|
|
|
|
i = AlertInfoStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AlertInfo.Length) {
|
|
int blockLength = AlertInfo[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AlertInfoStart) {
|
|
variableLength += blockLength;
|
|
++AlertInfoCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)AlertInfoCount;
|
|
for (i = AlertInfoStart; i < AlertInfoStart + AlertInfoCount; i++) { AlertInfo[i].ToBytes(packet, ref length); }
|
|
AlertInfoStart += AlertInfoCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
AlertInfoStart < AlertInfo.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UndoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public UndoPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.Undo;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 75;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public UndoPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public UndoPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RedoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public RedoPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.Redo;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 76;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public RedoPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public RedoPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UndoLandPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public UndoLandPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.UndoLand;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 77;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public UndoLandPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public UndoLandPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentPausePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint SerialNum;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
SerialNum = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(SerialNum, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public AgentPausePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentPause;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 78;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public AgentPausePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentPausePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentResumePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint SerialNum;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
SerialNum = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(SerialNum, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public AgentResumePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentResume;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 79;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public AgentResumePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentResumePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChatFromViewerPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChatDataBlock : PacketBlock
|
|
{
|
|
public byte[] Message;
|
|
public byte Type;
|
|
public int Channel;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
if (Message != null) { length += Message.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ChatDataBlock() { }
|
|
public ChatDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
Type = (byte)bytes[i++];
|
|
Channel = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(Message.Length % 256);
|
|
bytes[i++] = (byte)((Message.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
bytes[i++] = Type;
|
|
Utils.IntToBytes(Channel, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ChatData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ChatDataBlock ChatData;
|
|
|
|
public ChatFromViewerPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ChatFromViewer;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 80;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ChatData = new ChatDataBlock();
|
|
}
|
|
|
|
public ChatFromViewerPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ChatData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ChatFromViewerPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ChatData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ChatData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ChatData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentThrottlePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint CircuitCode;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
CircuitCode = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(CircuitCode, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ThrottleBlock : PacketBlock
|
|
{
|
|
public uint GenCounter;
|
|
public byte[] Throttles;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 5;
|
|
if (Throttles != null) { length += Throttles.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ThrottleBlock() { }
|
|
public ThrottleBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
GenCounter = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Throttles = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Throttles, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(GenCounter, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Throttles.Length;
|
|
Buffer.BlockCopy(Throttles, 0, bytes, i, Throttles.Length); i += Throttles.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Throttle.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ThrottleBlock Throttle;
|
|
|
|
public AgentThrottlePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentThrottle;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 81;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Throttle = new ThrottleBlock();
|
|
}
|
|
|
|
public AgentThrottlePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Throttle.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentThrottlePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Throttle.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Throttle.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Throttle.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentFOVPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint CircuitCode;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
CircuitCode = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(CircuitCode, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FOVBlockBlock : PacketBlock
|
|
{
|
|
public uint GenCounter;
|
|
public float VerticalAngle;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public FOVBlockBlock() { }
|
|
public FOVBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GenCounter = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
VerticalAngle = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(GenCounter, bytes, i); i += 4;
|
|
Utils.FloatToBytes(VerticalAngle, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += FOVBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public FOVBlockBlock FOVBlock;
|
|
|
|
public AgentFOVPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentFOV;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 82;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
FOVBlock = new FOVBlockBlock();
|
|
}
|
|
|
|
public AgentFOVPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
FOVBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentFOVPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
FOVBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += FOVBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
FOVBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentHeightWidthPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint CircuitCode;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
CircuitCode = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(CircuitCode, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class HeightWidthBlockBlock : PacketBlock
|
|
{
|
|
public uint GenCounter;
|
|
public ushort Height;
|
|
public ushort Width;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public HeightWidthBlockBlock() { }
|
|
public HeightWidthBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GenCounter = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Height = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
Width = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(GenCounter, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(Height % 256);
|
|
bytes[i++] = (byte)((Height >> 8) % 256);
|
|
bytes[i++] = (byte)(Width % 256);
|
|
bytes[i++] = (byte)((Width >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += HeightWidthBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public HeightWidthBlockBlock HeightWidthBlock;
|
|
|
|
public AgentHeightWidthPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentHeightWidth;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 83;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
HeightWidthBlock = new HeightWidthBlockBlock();
|
|
}
|
|
|
|
public AgentHeightWidthPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
HeightWidthBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentHeightWidthPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
HeightWidthBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += HeightWidthBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
HeightWidthBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentSetAppearancePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint SerialNum;
|
|
public Vector3 Size;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
SerialNum = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Size.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(SerialNum, bytes, i); i += 4;
|
|
Size.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class WearableDataBlock : PacketBlock
|
|
{
|
|
public UUID CacheID;
|
|
public byte TextureIndex;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public WearableDataBlock() { }
|
|
public WearableDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
CacheID.FromBytes(bytes, i); i += 16;
|
|
TextureIndex = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
CacheID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = TextureIndex;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public byte[] TextureEntry;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (TextureEntry != null) { length += TextureEntry.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
TextureEntry = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TextureEntry, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(TextureEntry.Length % 256);
|
|
bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256);
|
|
Buffer.BlockCopy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class VisualParamBlock : PacketBlock
|
|
{
|
|
public byte ParamValue;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public VisualParamBlock() { }
|
|
public VisualParamBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ParamValue = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = ParamValue;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < WearableData.Length; j++)
|
|
length += WearableData[j].Length;
|
|
length += ObjectData.Length;
|
|
for (int j = 0; j < VisualParam.Length; j++)
|
|
length += VisualParam[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public WearableDataBlock[] WearableData;
|
|
public ObjectDataBlock ObjectData;
|
|
public VisualParamBlock[] VisualParam;
|
|
|
|
public AgentSetAppearancePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AgentSetAppearance;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 84;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
WearableData = null;
|
|
ObjectData = new ObjectDataBlock();
|
|
VisualParam = null;
|
|
}
|
|
|
|
public AgentSetAppearancePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(WearableData == null || WearableData.Length != -1) {
|
|
WearableData = new WearableDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ WearableData[j] = new WearableDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ WearableData[j].FromBytes(bytes, ref i); }
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
count = (int)bytes[i++];
|
|
if(VisualParam == null || VisualParam.Length != -1) {
|
|
VisualParam = new VisualParamBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ VisualParam[j] = new VisualParamBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ VisualParam[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AgentSetAppearancePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(WearableData == null || WearableData.Length != count) {
|
|
WearableData = new WearableDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ WearableData[j] = new WearableDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ WearableData[j].FromBytes(bytes, ref i); }
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
count = (int)bytes[i++];
|
|
if(VisualParam == null || VisualParam.Length != count) {
|
|
VisualParam = new VisualParamBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ VisualParam[j] = new VisualParamBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ VisualParam[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
length++;
|
|
for (int j = 0; j < WearableData.Length; j++) { length += WearableData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < VisualParam.Length; j++) { length += VisualParam[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)WearableData.Length;
|
|
for (int j = 0; j < WearableData.Length; j++) { WearableData[j].ToBytes(bytes, ref i); }
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)VisualParam.Length;
|
|
for (int j = 0; j < VisualParam.Length; j++) { VisualParam[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentQuitCopyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FuseBlockBlock : PacketBlock
|
|
{
|
|
public uint ViewerCircuitCode;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public FuseBlockBlock() { }
|
|
public FuseBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ViewerCircuitCode = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ViewerCircuitCode, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += FuseBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public FuseBlockBlock FuseBlock;
|
|
|
|
public AgentQuitCopyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentQuitCopy;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 85;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
FuseBlock = new FuseBlockBlock();
|
|
}
|
|
|
|
public AgentQuitCopyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
FuseBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentQuitCopyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
FuseBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += FuseBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
FuseBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImageNotInDatabasePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ImageIDBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ImageIDBlock() { }
|
|
public ImageIDBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += ImageID.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ImageIDBlock ImageID;
|
|
|
|
public ImageNotInDatabasePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ImageNotInDatabase;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 86;
|
|
Header.Reliable = true;
|
|
ImageID = new ImageIDBlock();
|
|
}
|
|
|
|
public ImageNotInDatabasePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ImageID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ImageNotInDatabasePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ImageID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += ImageID.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ImageID.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RebakeAvatarTexturesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class TextureDataBlock : PacketBlock
|
|
{
|
|
public UUID TextureID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TextureDataBlock() { }
|
|
public TextureDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TextureID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TextureID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += TextureData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TextureDataBlock TextureData;
|
|
|
|
public RebakeAvatarTexturesPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RebakeAvatarTextures;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 87;
|
|
Header.Reliable = true;
|
|
TextureData = new TextureDataBlock();
|
|
}
|
|
|
|
public RebakeAvatarTexturesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TextureData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RebakeAvatarTexturesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TextureData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TextureData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TextureData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SetAlwaysRunPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public bool AlwaysRun;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
AlwaysRun = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((AlwaysRun) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public SetAlwaysRunPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SetAlwaysRun;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 88;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public SetAlwaysRunPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SetAlwaysRunPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDeletePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public bool Force;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
Force = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Force) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectDeletePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectDelete;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 89;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectDeletePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectDeletePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDuplicatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SharedDataBlock : PacketBlock
|
|
{
|
|
public Vector3 Offset;
|
|
public uint DuplicateFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public SharedDataBlock() { }
|
|
public SharedDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Offset.FromBytes(bytes, i); i += 12;
|
|
DuplicateFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Offset.ToBytes(bytes, i); i += 12;
|
|
Utils.UIntToBytes(DuplicateFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += SharedData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public SharedDataBlock SharedData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectDuplicatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectDuplicate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 90;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
SharedData = new SharedDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectDuplicatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
SharedData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectDuplicatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
SharedData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += SharedData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
SharedData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += SharedData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
SharedData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDuplicateOnRayPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
public Vector3 RayStart;
|
|
public Vector3 RayEnd;
|
|
public bool BypassRaycast;
|
|
public bool RayEndIsIntersection;
|
|
public bool CopyCenters;
|
|
public bool CopyRotates;
|
|
public UUID RayTargetID;
|
|
public uint DuplicateFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 96;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
RayStart.FromBytes(bytes, i); i += 12;
|
|
RayEnd.FromBytes(bytes, i); i += 12;
|
|
BypassRaycast = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
RayEndIsIntersection = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
CopyCenters = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
CopyRotates = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
RayTargetID.FromBytes(bytes, i); i += 16;
|
|
DuplicateFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
RayStart.ToBytes(bytes, i); i += 12;
|
|
RayEnd.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = (byte)((BypassRaycast) ? 1 : 0);
|
|
bytes[i++] = (byte)((RayEndIsIntersection) ? 1 : 0);
|
|
bytes[i++] = (byte)((CopyCenters) ? 1 : 0);
|
|
bytes[i++] = (byte)((CopyRotates) ? 1 : 0);
|
|
RayTargetID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(DuplicateFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectDuplicateOnRayPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectDuplicateOnRay;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 91;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectDuplicateOnRayPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectDuplicateOnRayPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectScalePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public Vector3 Scale;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Scale.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
Scale.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectScalePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectScale;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 92;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectScalePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectScalePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectRotationPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public Quaternion Rotation;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Rotation.FromBytes(bytes, i, true); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
Rotation.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectRotationPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectRotation;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 93;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectRotationPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectRotationPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectFlagUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint ObjectLocalID;
|
|
public bool UsePhysics;
|
|
public bool IsTemporary;
|
|
public bool IsPhantom;
|
|
public bool CastsShadows;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 40;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
UsePhysics = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
IsTemporary = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
IsPhantom = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
CastsShadows = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((UsePhysics) ? 1 : 0);
|
|
bytes[i++] = (byte)((IsTemporary) ? 1 : 0);
|
|
bytes[i++] = (byte)((IsPhantom) ? 1 : 0);
|
|
bytes[i++] = (byte)((CastsShadows) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ExtraPhysicsBlock : PacketBlock
|
|
{
|
|
public byte PhysicsShapeType;
|
|
public float Density;
|
|
public float Friction;
|
|
public float Restitution;
|
|
public float GravityMultiplier;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public ExtraPhysicsBlock() { }
|
|
public ExtraPhysicsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
PhysicsShapeType = (byte)bytes[i++];
|
|
Density = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Friction = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Restitution = Utils.BytesToFloat(bytes, i); i += 4;
|
|
GravityMultiplier = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = PhysicsShapeType;
|
|
Utils.FloatToBytes(Density, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Friction, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Restitution, bytes, i); i += 4;
|
|
Utils.FloatToBytes(GravityMultiplier, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ExtraPhysics.Length; j++)
|
|
length += ExtraPhysics[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ExtraPhysicsBlock[] ExtraPhysics;
|
|
|
|
public ObjectFlagUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectFlagUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 94;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ExtraPhysics = null;
|
|
}
|
|
|
|
public ObjectFlagUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ExtraPhysics == null || ExtraPhysics.Length != -1) {
|
|
ExtraPhysics = new ExtraPhysicsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ExtraPhysics[j] = new ExtraPhysicsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ExtraPhysics[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectFlagUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ExtraPhysics == null || ExtraPhysics.Length != count) {
|
|
ExtraPhysics = new ExtraPhysicsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ExtraPhysics[j] = new ExtraPhysicsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ExtraPhysics[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ExtraPhysics.Length; j++) { length += ExtraPhysics[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ExtraPhysics.Length;
|
|
for (int j = 0; j < ExtraPhysics.Length; j++) { ExtraPhysics[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ExtraPhysicsStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ExtraPhysicsCount = 0;
|
|
|
|
i = ExtraPhysicsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ExtraPhysics.Length) {
|
|
int blockLength = ExtraPhysics[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ExtraPhysicsStart) {
|
|
variableLength += blockLength;
|
|
++ExtraPhysicsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ExtraPhysicsCount;
|
|
for (i = ExtraPhysicsStart; i < ExtraPhysicsStart + ExtraPhysicsCount; i++) { ExtraPhysics[i].ToBytes(packet, ref length); }
|
|
ExtraPhysicsStart += ExtraPhysicsCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ExtraPhysicsStart < ExtraPhysics.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectClickActionPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public byte ClickAction;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 5;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ClickAction = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = ClickAction;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectClickActionPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectClickAction;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 95;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectClickActionPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectClickActionPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectImagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public byte[] MediaURL;
|
|
public byte[] TextureEntry;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
if (MediaURL != null) { length += MediaURL.Length; }
|
|
if (TextureEntry != null) { length += TextureEntry.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
MediaURL = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MediaURL, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
TextureEntry = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TextureEntry, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)MediaURL.Length;
|
|
Buffer.BlockCopy(MediaURL, 0, bytes, i, MediaURL.Length); i += MediaURL.Length;
|
|
bytes[i++] = (byte)(TextureEntry.Length % 256);
|
|
bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256);
|
|
Buffer.BlockCopy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectImagePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectImage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 96;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectImagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectImagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectMaterialPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public byte Material;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 5;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Material = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = Material;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectMaterialPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectMaterial;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 97;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectMaterialPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectMaterialPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectShapePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public byte PathCurve;
|
|
public byte ProfileCurve;
|
|
public ushort PathBegin;
|
|
public ushort PathEnd;
|
|
public byte PathScaleX;
|
|
public byte PathScaleY;
|
|
public byte PathShearX;
|
|
public byte PathShearY;
|
|
public sbyte PathTwist;
|
|
public sbyte PathTwistBegin;
|
|
public sbyte PathRadiusOffset;
|
|
public sbyte PathTaperX;
|
|
public sbyte PathTaperY;
|
|
public byte PathRevolutions;
|
|
public sbyte PathSkew;
|
|
public ushort ProfileBegin;
|
|
public ushort ProfileEnd;
|
|
public ushort ProfileHollow;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 27;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PathCurve = (byte)bytes[i++];
|
|
ProfileCurve = (byte)bytes[i++];
|
|
PathBegin = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
PathEnd = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
PathScaleX = (byte)bytes[i++];
|
|
PathScaleY = (byte)bytes[i++];
|
|
PathShearX = (byte)bytes[i++];
|
|
PathShearY = (byte)bytes[i++];
|
|
PathTwist = (sbyte)bytes[i++];
|
|
PathTwistBegin = (sbyte)bytes[i++];
|
|
PathRadiusOffset = (sbyte)bytes[i++];
|
|
PathTaperX = (sbyte)bytes[i++];
|
|
PathTaperY = (sbyte)bytes[i++];
|
|
PathRevolutions = (byte)bytes[i++];
|
|
PathSkew = (sbyte)bytes[i++];
|
|
ProfileBegin = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
ProfileEnd = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
ProfileHollow = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = PathCurve;
|
|
bytes[i++] = ProfileCurve;
|
|
bytes[i++] = (byte)(PathBegin % 256);
|
|
bytes[i++] = (byte)((PathBegin >> 8) % 256);
|
|
bytes[i++] = (byte)(PathEnd % 256);
|
|
bytes[i++] = (byte)((PathEnd >> 8) % 256);
|
|
bytes[i++] = PathScaleX;
|
|
bytes[i++] = PathScaleY;
|
|
bytes[i++] = PathShearX;
|
|
bytes[i++] = PathShearY;
|
|
bytes[i++] = (byte)PathTwist;
|
|
bytes[i++] = (byte)PathTwistBegin;
|
|
bytes[i++] = (byte)PathRadiusOffset;
|
|
bytes[i++] = (byte)PathTaperX;
|
|
bytes[i++] = (byte)PathTaperY;
|
|
bytes[i++] = PathRevolutions;
|
|
bytes[i++] = (byte)PathSkew;
|
|
bytes[i++] = (byte)(ProfileBegin % 256);
|
|
bytes[i++] = (byte)((ProfileBegin >> 8) % 256);
|
|
bytes[i++] = (byte)(ProfileEnd % 256);
|
|
bytes[i++] = (byte)((ProfileEnd >> 8) % 256);
|
|
bytes[i++] = (byte)(ProfileHollow % 256);
|
|
bytes[i++] = (byte)((ProfileHollow >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectShapePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectShape;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 98;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectShapePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectShapePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectExtraParamsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public ushort ParamType;
|
|
public bool ParamInUse;
|
|
public uint ParamSize;
|
|
public byte[] ParamData;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
if (ParamData != null) { length += ParamData.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ParamType = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
ParamInUse = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
ParamSize = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
ParamData = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ParamData, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(ParamType % 256);
|
|
bytes[i++] = (byte)((ParamType >> 8) % 256);
|
|
bytes[i++] = (byte)((ParamInUse) ? 1 : 0);
|
|
Utils.UIntToBytes(ParamSize, bytes, i); i += 4;
|
|
bytes[i++] = (byte)ParamData.Length;
|
|
Buffer.BlockCopy(ParamData, 0, bytes, i, ParamData.Length); i += ParamData.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectExtraParamsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectExtraParams;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 99;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectExtraParamsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectExtraParamsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectOwnerPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class HeaderDataBlock : PacketBlock
|
|
{
|
|
public bool Override;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public HeaderDataBlock() { }
|
|
public HeaderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Override = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((Override) ? 1 : 0);
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += HeaderData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public HeaderDataBlock HeaderData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectOwnerPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectOwner;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 100;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
HeaderData = new HeaderDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectOwnerPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
HeaderData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectOwnerPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
HeaderData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += HeaderData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
HeaderData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += HeaderData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
HeaderData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectGroupPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectGroupPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectGroup;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 101;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectGroupPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectGroupPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectBuyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
public UUID CategoryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 64;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
CategoryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
CategoryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 9;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectBuyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectBuy;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 102;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectBuyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectBuyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class BuyObjectInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public BuyObjectInventoryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.BuyObjectInventory;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 103;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public BuyObjectInventoryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public BuyObjectInventoryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DerezContainerPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public bool Delete;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
Delete = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Delete) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock Data;
|
|
|
|
public DerezContainerPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DerezContainer;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 104;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public DerezContainerPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public DerezContainerPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectPermissionsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class HeaderDataBlock : PacketBlock
|
|
{
|
|
public bool Override;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public HeaderDataBlock() { }
|
|
public HeaderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Override = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((Override) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public byte Field;
|
|
public byte Set;
|
|
public uint Mask;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 10;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Field = (byte)bytes[i++];
|
|
Set = (byte)bytes[i++];
|
|
Mask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = Field;
|
|
bytes[i++] = Set;
|
|
Utils.UIntToBytes(Mask, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += HeaderData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public HeaderDataBlock HeaderData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectPermissionsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectPermissions;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 105;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
HeaderData = new HeaderDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectPermissionsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
HeaderData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectPermissionsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
HeaderData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += HeaderData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
HeaderData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += HeaderData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
HeaderData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectSaleInfoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 9;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectSaleInfoPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectSaleInfo;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 106;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectSaleInfoPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectSaleInfoPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectNamePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
public byte[] Name;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 5;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectNamePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectName;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 107;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectNamePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectNamePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDescriptionPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
public byte[] Description;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 5;
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectDescriptionPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectDescription;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 108;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectDescriptionPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectDescriptionPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectCategoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
public uint Category;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Category = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Category, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectCategoryPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectCategory;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 109;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectCategoryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectCategoryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectSelectPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectSelectPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectSelect;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 110;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectSelectPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectSelectPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDeselectPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectDeselectPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectDeselect;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 111;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectDeselectPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectDeselectPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectAttachPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public byte AttachmentPoint;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
AttachmentPoint = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = AttachmentPoint;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public Quaternion Rotation;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Rotation.FromBytes(bytes, i, true); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
Rotation.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectAttachPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectAttach;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 112;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectAttachPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectAttachPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDetachPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectDetachPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectDetach;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 113;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectDetachPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectDetachPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDropPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectDropPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectDrop;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 114;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectDropPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectDropPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectLinkPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectLinkPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectLink;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 115;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectLinkPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectLinkPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDelinkPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectDelinkPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectDelink;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 116;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectDelinkPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectDelinkPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectGrabPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
public Vector3 GrabOffset;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GrabOffset.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
GrabOffset.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SurfaceInfoBlock : PacketBlock
|
|
{
|
|
public Vector3 UVCoord;
|
|
public Vector3 STCoord;
|
|
public int FaceIndex;
|
|
public Vector3 Position;
|
|
public Vector3 Normal;
|
|
public Vector3 Binormal;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 64;
|
|
}
|
|
}
|
|
|
|
public SurfaceInfoBlock() { }
|
|
public SurfaceInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
UVCoord.FromBytes(bytes, i); i += 12;
|
|
STCoord.FromBytes(bytes, i); i += 12;
|
|
FaceIndex = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
Normal.FromBytes(bytes, i); i += 12;
|
|
Binormal.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
UVCoord.ToBytes(bytes, i); i += 12;
|
|
STCoord.ToBytes(bytes, i); i += 12;
|
|
Utils.IntToBytes(FaceIndex, bytes, i); i += 4;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
Normal.ToBytes(bytes, i); i += 12;
|
|
Binormal.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
for (int j = 0; j < SurfaceInfo.Length; j++)
|
|
length += SurfaceInfo[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock ObjectData;
|
|
public SurfaceInfoBlock[] SurfaceInfo;
|
|
|
|
public ObjectGrabPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectGrab;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 117;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = new ObjectDataBlock();
|
|
SurfaceInfo = null;
|
|
}
|
|
|
|
public ObjectGrabPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(SurfaceInfo == null || SurfaceInfo.Length != -1) {
|
|
SurfaceInfo = new SurfaceInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j] = new SurfaceInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectGrabPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(SurfaceInfo == null || SurfaceInfo.Length != count) {
|
|
SurfaceInfo = new SurfaceInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j] = new SurfaceInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
length++;
|
|
for (int j = 0; j < SurfaceInfo.Length; j++) { length += SurfaceInfo[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)SurfaceInfo.Length;
|
|
for (int j = 0; j < SurfaceInfo.Length; j++) { SurfaceInfo[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += ObjectData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
ObjectData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int SurfaceInfoStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int SurfaceInfoCount = 0;
|
|
|
|
i = SurfaceInfoStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < SurfaceInfo.Length) {
|
|
int blockLength = SurfaceInfo[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == SurfaceInfoStart) {
|
|
variableLength += blockLength;
|
|
++SurfaceInfoCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)SurfaceInfoCount;
|
|
for (i = SurfaceInfoStart; i < SurfaceInfoStart + SurfaceInfoCount; i++) { SurfaceInfo[i].ToBytes(packet, ref length); }
|
|
SurfaceInfoStart += SurfaceInfoCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
SurfaceInfoStart < SurfaceInfo.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectGrabUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public Vector3 GrabOffsetInitial;
|
|
public Vector3 GrabPosition;
|
|
public uint TimeSinceLast;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 44;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
GrabOffsetInitial.FromBytes(bytes, i); i += 12;
|
|
GrabPosition.FromBytes(bytes, i); i += 12;
|
|
TimeSinceLast = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
GrabOffsetInitial.ToBytes(bytes, i); i += 12;
|
|
GrabPosition.ToBytes(bytes, i); i += 12;
|
|
Utils.UIntToBytes(TimeSinceLast, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SurfaceInfoBlock : PacketBlock
|
|
{
|
|
public Vector3 UVCoord;
|
|
public Vector3 STCoord;
|
|
public int FaceIndex;
|
|
public Vector3 Position;
|
|
public Vector3 Normal;
|
|
public Vector3 Binormal;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 64;
|
|
}
|
|
}
|
|
|
|
public SurfaceInfoBlock() { }
|
|
public SurfaceInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
UVCoord.FromBytes(bytes, i); i += 12;
|
|
STCoord.FromBytes(bytes, i); i += 12;
|
|
FaceIndex = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
Normal.FromBytes(bytes, i); i += 12;
|
|
Binormal.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
UVCoord.ToBytes(bytes, i); i += 12;
|
|
STCoord.ToBytes(bytes, i); i += 12;
|
|
Utils.IntToBytes(FaceIndex, bytes, i); i += 4;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
Normal.ToBytes(bytes, i); i += 12;
|
|
Binormal.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
for (int j = 0; j < SurfaceInfo.Length; j++)
|
|
length += SurfaceInfo[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock ObjectData;
|
|
public SurfaceInfoBlock[] SurfaceInfo;
|
|
|
|
public ObjectGrabUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectGrabUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 118;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = new ObjectDataBlock();
|
|
SurfaceInfo = null;
|
|
}
|
|
|
|
public ObjectGrabUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(SurfaceInfo == null || SurfaceInfo.Length != -1) {
|
|
SurfaceInfo = new SurfaceInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j] = new SurfaceInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectGrabUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(SurfaceInfo == null || SurfaceInfo.Length != count) {
|
|
SurfaceInfo = new SurfaceInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j] = new SurfaceInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
length++;
|
|
for (int j = 0; j < SurfaceInfo.Length; j++) { length += SurfaceInfo[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)SurfaceInfo.Length;
|
|
for (int j = 0; j < SurfaceInfo.Length; j++) { SurfaceInfo[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += ObjectData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
ObjectData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int SurfaceInfoStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int SurfaceInfoCount = 0;
|
|
|
|
i = SurfaceInfoStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < SurfaceInfo.Length) {
|
|
int blockLength = SurfaceInfo[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == SurfaceInfoStart) {
|
|
variableLength += blockLength;
|
|
++SurfaceInfoCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)SurfaceInfoCount;
|
|
for (i = SurfaceInfoStart; i < SurfaceInfoStart + SurfaceInfoCount; i++) { SurfaceInfo[i].ToBytes(packet, ref length); }
|
|
SurfaceInfoStart += SurfaceInfoCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
SurfaceInfoStart < SurfaceInfo.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDeGrabPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SurfaceInfoBlock : PacketBlock
|
|
{
|
|
public Vector3 UVCoord;
|
|
public Vector3 STCoord;
|
|
public int FaceIndex;
|
|
public Vector3 Position;
|
|
public Vector3 Normal;
|
|
public Vector3 Binormal;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 64;
|
|
}
|
|
}
|
|
|
|
public SurfaceInfoBlock() { }
|
|
public SurfaceInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
UVCoord.FromBytes(bytes, i); i += 12;
|
|
STCoord.FromBytes(bytes, i); i += 12;
|
|
FaceIndex = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
Normal.FromBytes(bytes, i); i += 12;
|
|
Binormal.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
UVCoord.ToBytes(bytes, i); i += 12;
|
|
STCoord.ToBytes(bytes, i); i += 12;
|
|
Utils.IntToBytes(FaceIndex, bytes, i); i += 4;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
Normal.ToBytes(bytes, i); i += 12;
|
|
Binormal.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
for (int j = 0; j < SurfaceInfo.Length; j++)
|
|
length += SurfaceInfo[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock ObjectData;
|
|
public SurfaceInfoBlock[] SurfaceInfo;
|
|
|
|
public ObjectDeGrabPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectDeGrab;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 119;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = new ObjectDataBlock();
|
|
SurfaceInfo = null;
|
|
}
|
|
|
|
public ObjectDeGrabPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(SurfaceInfo == null || SurfaceInfo.Length != -1) {
|
|
SurfaceInfo = new SurfaceInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j] = new SurfaceInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectDeGrabPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(SurfaceInfo == null || SurfaceInfo.Length != count) {
|
|
SurfaceInfo = new SurfaceInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j] = new SurfaceInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ SurfaceInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
length++;
|
|
for (int j = 0; j < SurfaceInfo.Length; j++) { length += SurfaceInfo[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)SurfaceInfo.Length;
|
|
for (int j = 0; j < SurfaceInfo.Length; j++) { SurfaceInfo[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += ObjectData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
ObjectData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int SurfaceInfoStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int SurfaceInfoCount = 0;
|
|
|
|
i = SurfaceInfoStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < SurfaceInfo.Length) {
|
|
int blockLength = SurfaceInfo[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == SurfaceInfoStart) {
|
|
variableLength += blockLength;
|
|
++SurfaceInfoCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)SurfaceInfoCount;
|
|
for (i = SurfaceInfoStart; i < SurfaceInfoStart + SurfaceInfoCount; i++) { SurfaceInfo[i].ToBytes(packet, ref length); }
|
|
SurfaceInfoStart += SurfaceInfoCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
SurfaceInfoStart < SurfaceInfo.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectSpinStartPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock ObjectData;
|
|
|
|
public ObjectSpinStartPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ObjectSpinStart;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 120;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = new ObjectDataBlock();
|
|
}
|
|
|
|
public ObjectSpinStartPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ObjectSpinStartPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectSpinUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public Quaternion Rotation;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 28;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
Rotation.FromBytes(bytes, i, true); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
Rotation.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock ObjectData;
|
|
|
|
public ObjectSpinUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ObjectSpinUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 121;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = new ObjectDataBlock();
|
|
}
|
|
|
|
public ObjectSpinUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ObjectSpinUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectSpinStopPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock ObjectData;
|
|
|
|
public ObjectSpinStopPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ObjectSpinStop;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 122;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = new ObjectDataBlock();
|
|
}
|
|
|
|
public ObjectSpinStopPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ObjectSpinStopPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectExportSelectedPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID RequestID;
|
|
public short VolumeDetail;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 34;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
VolumeDetail = (short)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)(VolumeDetail % 256);
|
|
bytes[i++] = (byte)((VolumeDetail >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectExportSelectedPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectExportSelected;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 123;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectExportSelectedPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectExportSelectedPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ModifyLandPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ModifyBlockBlock : PacketBlock
|
|
{
|
|
public byte Action;
|
|
public byte BrushSize;
|
|
public float Seconds;
|
|
public float Height;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 10;
|
|
}
|
|
}
|
|
|
|
public ModifyBlockBlock() { }
|
|
public ModifyBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Action = (byte)bytes[i++];
|
|
BrushSize = (byte)bytes[i++];
|
|
Seconds = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Height = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = Action;
|
|
bytes[i++] = BrushSize;
|
|
Utils.FloatToBytes(Seconds, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Height, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
public float West;
|
|
public float South;
|
|
public float East;
|
|
public float North;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
West = Utils.BytesToFloat(bytes, i); i += 4;
|
|
South = Utils.BytesToFloat(bytes, i); i += 4;
|
|
East = Utils.BytesToFloat(bytes, i); i += 4;
|
|
North = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
Utils.FloatToBytes(West, bytes, i); i += 4;
|
|
Utils.FloatToBytes(South, bytes, i); i += 4;
|
|
Utils.FloatToBytes(East, bytes, i); i += 4;
|
|
Utils.FloatToBytes(North, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ModifyBlockExtendedBlock : PacketBlock
|
|
{
|
|
public float BrushSize;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ModifyBlockExtendedBlock() { }
|
|
public ModifyBlockExtendedBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
BrushSize = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.FloatToBytes(BrushSize, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
length += ModifyBlock.Length;
|
|
for (int j = 0; j < ParcelData.Length; j++)
|
|
length += ParcelData[j].Length;
|
|
for (int j = 0; j < ModifyBlockExtended.Length; j++)
|
|
length += ModifyBlockExtended[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ModifyBlockBlock ModifyBlock;
|
|
public ParcelDataBlock[] ParcelData;
|
|
public ModifyBlockExtendedBlock[] ModifyBlockExtended;
|
|
|
|
public ModifyLandPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ModifyLand;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 124;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ModifyBlock = new ModifyBlockBlock();
|
|
ParcelData = null;
|
|
ModifyBlockExtended = null;
|
|
}
|
|
|
|
public ModifyLandPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ModifyBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParcelData == null || ParcelData.Length != -1) {
|
|
ParcelData = new ParcelDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParcelData[j] = new ParcelDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParcelData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(ModifyBlockExtended == null || ModifyBlockExtended.Length != -1) {
|
|
ModifyBlockExtended = new ModifyBlockExtendedBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ModifyBlockExtended[j] = new ModifyBlockExtendedBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ModifyBlockExtended[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ModifyLandPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ModifyBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParcelData == null || ParcelData.Length != count) {
|
|
ParcelData = new ParcelDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParcelData[j] = new ParcelDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParcelData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(ModifyBlockExtended == null || ModifyBlockExtended.Length != count) {
|
|
ModifyBlockExtended = new ModifyBlockExtendedBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ModifyBlockExtended[j] = new ModifyBlockExtendedBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ModifyBlockExtended[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ModifyBlock.Length;
|
|
length++;
|
|
for (int j = 0; j < ParcelData.Length; j++) { length += ParcelData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < ModifyBlockExtended.Length; j++) { length += ModifyBlockExtended[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ModifyBlock.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ParcelData.Length;
|
|
for (int j = 0; j < ParcelData.Length; j++) { ParcelData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)ModifyBlockExtended.Length;
|
|
for (int j = 0; j < ModifyBlockExtended.Length; j++) { ModifyBlockExtended[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += ModifyBlock.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
ModifyBlock.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int ParcelDataStart = 0;
|
|
int ModifyBlockExtendedStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ParcelDataCount = 0;
|
|
int ModifyBlockExtendedCount = 0;
|
|
|
|
i = ParcelDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ParcelData.Length) {
|
|
int blockLength = ParcelData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ParcelDataStart) {
|
|
variableLength += blockLength;
|
|
++ParcelDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = ModifyBlockExtendedStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ModifyBlockExtended.Length) {
|
|
int blockLength = ModifyBlockExtended[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ModifyBlockExtendedStart) {
|
|
variableLength += blockLength;
|
|
++ModifyBlockExtendedCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ParcelDataCount;
|
|
for (i = ParcelDataStart; i < ParcelDataStart + ParcelDataCount; i++) { ParcelData[i].ToBytes(packet, ref length); }
|
|
ParcelDataStart += ParcelDataCount;
|
|
|
|
packet[length++] = (byte)ModifyBlockExtendedCount;
|
|
for (i = ModifyBlockExtendedStart; i < ModifyBlockExtendedStart + ModifyBlockExtendedCount; i++) { ModifyBlockExtended[i].ToBytes(packet, ref length); }
|
|
ModifyBlockExtendedStart += ModifyBlockExtendedCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ParcelDataStart < ParcelData.Length ||
|
|
ModifyBlockExtendedStart < ModifyBlockExtended.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class VelocityInterpolateOnPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public VelocityInterpolateOnPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.VelocityInterpolateOn;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 125;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public VelocityInterpolateOnPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public VelocityInterpolateOnPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class VelocityInterpolateOffPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public VelocityInterpolateOffPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.VelocityInterpolateOff;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 126;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public VelocityInterpolateOffPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public VelocityInterpolateOffPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StateSavePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlockBlock : PacketBlock
|
|
{
|
|
public byte[] Filename;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (Filename != null) { length += Filename.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlockBlock() { }
|
|
public DataBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Filename = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Filename, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Filename.Length;
|
|
Buffer.BlockCopy(Filename, 0, bytes, i, Filename.Length); i += Filename.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += DataBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlockBlock DataBlock;
|
|
|
|
public StateSavePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.StateSave;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 127;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
DataBlock = new DataBlockBlock();
|
|
}
|
|
|
|
public StateSavePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public StateSavePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += DataBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
DataBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ReportAutosaveCrashPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AutosaveDataBlock : PacketBlock
|
|
{
|
|
public int PID;
|
|
public int Status;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public AutosaveDataBlock() { }
|
|
public AutosaveDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
PID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Status = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(PID, bytes, i); i += 4;
|
|
Utils.IntToBytes(Status, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AutosaveData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AutosaveDataBlock AutosaveData;
|
|
|
|
public ReportAutosaveCrashPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ReportAutosaveCrash;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 128;
|
|
Header.Reliable = true;
|
|
AutosaveData = new AutosaveDataBlock();
|
|
}
|
|
|
|
public ReportAutosaveCrashPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AutosaveData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ReportAutosaveCrashPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AutosaveData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AutosaveData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AutosaveData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SimWideDeletesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlockBlock : PacketBlock
|
|
{
|
|
public UUID TargetID;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public DataBlockBlock() { }
|
|
public DataBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TargetID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TargetID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += DataBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlockBlock DataBlock;
|
|
|
|
public SimWideDeletesPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SimWideDeletes;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 129;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
DataBlock = new DataBlockBlock();
|
|
}
|
|
|
|
public SimWideDeletesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SimWideDeletesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += DataBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
DataBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TrackAgentPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TargetDataBlock : PacketBlock
|
|
{
|
|
public UUID PreyID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TargetDataBlock() { }
|
|
public TargetDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
PreyID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
PreyID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TargetData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public TargetDataBlock TargetData;
|
|
|
|
public TrackAgentPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TrackAgent;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 130;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
TargetData = new TargetDataBlock();
|
|
}
|
|
|
|
public TrackAgentPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TargetData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TrackAgentPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TargetData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TargetData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TargetData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ViewerStatsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint IP;
|
|
public uint StartTime;
|
|
public float RunTime;
|
|
public float SimFPS;
|
|
public float FPS;
|
|
public byte AgentsInView;
|
|
public float Ping;
|
|
public double MetersTraveled;
|
|
public int RegionsVisited;
|
|
public uint SysRAM;
|
|
public byte[] SysOS;
|
|
public byte[] SysCPU;
|
|
public byte[] SysGPU;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 76;
|
|
if (SysOS != null) { length += SysOS.Length; }
|
|
if (SysCPU != null) { length += SysCPU.Length; }
|
|
if (SysGPU != null) { length += SysGPU.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
IP = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
StartTime = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RunTime = Utils.BytesToFloat(bytes, i); i += 4;
|
|
SimFPS = Utils.BytesToFloat(bytes, i); i += 4;
|
|
FPS = Utils.BytesToFloat(bytes, i); i += 4;
|
|
AgentsInView = (byte)bytes[i++];
|
|
Ping = Utils.BytesToFloat(bytes, i); i += 4;
|
|
MetersTraveled = Utils.BytesToDouble(bytes, i); i += 8;
|
|
RegionsVisited = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SysRAM = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
SysOS = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SysOS, 0, length); i += length;
|
|
length = bytes[i++];
|
|
SysCPU = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SysCPU, 0, length); i += length;
|
|
length = bytes[i++];
|
|
SysGPU = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SysGPU, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(IP, bytes, i); i += 4;
|
|
Utils.UIntToBytes(StartTime, bytes, i); i += 4;
|
|
Utils.FloatToBytes(RunTime, bytes, i); i += 4;
|
|
Utils.FloatToBytes(SimFPS, bytes, i); i += 4;
|
|
Utils.FloatToBytes(FPS, bytes, i); i += 4;
|
|
bytes[i++] = AgentsInView;
|
|
Utils.FloatToBytes(Ping, bytes, i); i += 4;
|
|
Utils.DoubleToBytes(MetersTraveled, bytes, i); i += 8;
|
|
Utils.IntToBytes(RegionsVisited, bytes, i); i += 4;
|
|
Utils.UIntToBytes(SysRAM, bytes, i); i += 4;
|
|
bytes[i++] = (byte)SysOS.Length;
|
|
Buffer.BlockCopy(SysOS, 0, bytes, i, SysOS.Length); i += SysOS.Length;
|
|
bytes[i++] = (byte)SysCPU.Length;
|
|
Buffer.BlockCopy(SysCPU, 0, bytes, i, SysCPU.Length); i += SysCPU.Length;
|
|
bytes[i++] = (byte)SysGPU.Length;
|
|
Buffer.BlockCopy(SysGPU, 0, bytes, i, SysGPU.Length); i += SysGPU.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DownloadTotalsBlock : PacketBlock
|
|
{
|
|
public uint World;
|
|
public uint Objects;
|
|
public uint Textures;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public DownloadTotalsBlock() { }
|
|
public DownloadTotalsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
World = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Objects = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Textures = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(World, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Objects, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Textures, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class NetStatsBlock : PacketBlock
|
|
{
|
|
public uint Bytes;
|
|
public uint Packets;
|
|
public uint Compressed;
|
|
public uint Savings;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public NetStatsBlock() { }
|
|
public NetStatsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Bytes = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Packets = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Compressed = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Savings = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Bytes, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Packets, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Compressed, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Savings, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FailStatsBlock : PacketBlock
|
|
{
|
|
public uint SendPacket;
|
|
public uint Dropped;
|
|
public uint Resent;
|
|
public uint FailedResends;
|
|
public uint OffCircuit;
|
|
public uint Invalid;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 24;
|
|
}
|
|
}
|
|
|
|
public FailStatsBlock() { }
|
|
public FailStatsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
SendPacket = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Dropped = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Resent = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
FailedResends = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OffCircuit = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Invalid = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(SendPacket, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Dropped, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Resent, bytes, i); i += 4;
|
|
Utils.UIntToBytes(FailedResends, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OffCircuit, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Invalid, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MiscStatsBlock : PacketBlock
|
|
{
|
|
public uint Type;
|
|
public double Value;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public MiscStatsBlock() { }
|
|
public MiscStatsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Type = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Value = Utils.BytesToDouble(bytes, i); i += 8;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Type, bytes, i); i += 4;
|
|
Utils.DoubleToBytes(Value, bytes, i); i += 8;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += DownloadTotals.Length;
|
|
for (int j = 0; j < 2; j++)
|
|
length += NetStats[j].Length;
|
|
length += FailStats.Length;
|
|
for (int j = 0; j < MiscStats.Length; j++)
|
|
length += MiscStats[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DownloadTotalsBlock DownloadTotals;
|
|
public NetStatsBlock[] NetStats;
|
|
public FailStatsBlock FailStats;
|
|
public MiscStatsBlock[] MiscStats;
|
|
|
|
public ViewerStatsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ViewerStats;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 131;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
DownloadTotals = new DownloadTotalsBlock();
|
|
NetStats = new NetStatsBlock[2];
|
|
FailStats = new FailStatsBlock();
|
|
MiscStats = null;
|
|
}
|
|
|
|
public ViewerStatsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
DownloadTotals.FromBytes(bytes, ref i);
|
|
if(NetStats == null || NetStats.Length != 2) {
|
|
NetStats = new NetStatsBlock[2];
|
|
for(int j = 0; j < 2; j++)
|
|
{ NetStats[j] = new NetStatsBlock(); }
|
|
}
|
|
for (int j = 0; j < 2; j++)
|
|
{ NetStats[j].FromBytes(bytes, ref i); }
|
|
FailStats.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(MiscStats == null || MiscStats.Length != -1) {
|
|
MiscStats = new MiscStatsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ MiscStats[j] = new MiscStatsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ MiscStats[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ViewerStatsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
DownloadTotals.FromBytes(bytes, ref i);
|
|
if(NetStats == null || NetStats.Length != 2) {
|
|
NetStats = new NetStatsBlock[2];
|
|
for(int j = 0; j < 2; j++)
|
|
{ NetStats[j] = new NetStatsBlock(); }
|
|
}
|
|
for (int j = 0; j < 2; j++)
|
|
{ NetStats[j].FromBytes(bytes, ref i); }
|
|
FailStats.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(MiscStats == null || MiscStats.Length != count) {
|
|
MiscStats = new MiscStatsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ MiscStats[j] = new MiscStatsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ MiscStats[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += DownloadTotals.Length;
|
|
length += FailStats.Length;
|
|
for (int j = 0; j < 2; j++) { length += NetStats[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < MiscStats.Length; j++) { length += MiscStats[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
DownloadTotals.ToBytes(bytes, ref i);
|
|
for (int j = 0; j < 2; j++) { NetStats[j].ToBytes(bytes, ref i); }
|
|
FailStats.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)MiscStats.Length;
|
|
for (int j = 0; j < MiscStats.Length; j++) { MiscStats[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += DownloadTotals.Length;
|
|
for (int j = 0; j < 2; j++) { fixedLength += NetStats[j].Length; }
|
|
fixedLength += FailStats.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
DownloadTotals.ToBytes(fixedBytes, ref i);
|
|
for (int j = 0; j < 2; j++) { NetStats[j].ToBytes(fixedBytes, ref i); }
|
|
FailStats.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int MiscStatsStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int MiscStatsCount = 0;
|
|
|
|
i = MiscStatsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < MiscStats.Length) {
|
|
int blockLength = MiscStats[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == MiscStatsStart) {
|
|
variableLength += blockLength;
|
|
++MiscStatsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)MiscStatsCount;
|
|
for (i = MiscStatsStart; i < MiscStatsStart + MiscStatsCount; i++) { MiscStats[i].ToBytes(packet, ref length); }
|
|
MiscStatsStart += MiscStatsCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
MiscStatsStart < MiscStats.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptAnswerYesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID TaskID;
|
|
public UUID ItemID;
|
|
public int Questions;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TaskID.FromBytes(bytes, i); i += 16;
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
Questions = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TaskID.ToBytes(bytes, i); i += 16;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(Questions, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ScriptAnswerYesPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ScriptAnswerYes;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 132;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ScriptAnswerYesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ScriptAnswerYesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UserReportPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ReportDataBlock : PacketBlock
|
|
{
|
|
public byte ReportType;
|
|
public byte Category;
|
|
public Vector3 Position;
|
|
public byte CheckFlags;
|
|
public UUID ScreenshotID;
|
|
public UUID ObjectID;
|
|
public UUID AbuserID;
|
|
public byte[] AbuseRegionName;
|
|
public UUID AbuseRegionID;
|
|
public byte[] Summary;
|
|
public byte[] Details;
|
|
public byte[] VersionString;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 84;
|
|
if (AbuseRegionName != null) { length += AbuseRegionName.Length; }
|
|
if (Summary != null) { length += Summary.Length; }
|
|
if (Details != null) { length += Details.Length; }
|
|
if (VersionString != null) { length += VersionString.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ReportDataBlock() { }
|
|
public ReportDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ReportType = (byte)bytes[i++];
|
|
Category = (byte)bytes[i++];
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
CheckFlags = (byte)bytes[i++];
|
|
ScreenshotID.FromBytes(bytes, i); i += 16;
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
AbuserID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
AbuseRegionName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, AbuseRegionName, 0, length); i += length;
|
|
AbuseRegionID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Summary = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Summary, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Details = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Details, 0, length); i += length;
|
|
length = bytes[i++];
|
|
VersionString = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, VersionString, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = ReportType;
|
|
bytes[i++] = Category;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = CheckFlags;
|
|
ScreenshotID.ToBytes(bytes, i); i += 16;
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
AbuserID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)AbuseRegionName.Length;
|
|
Buffer.BlockCopy(AbuseRegionName, 0, bytes, i, AbuseRegionName.Length); i += AbuseRegionName.Length;
|
|
AbuseRegionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Summary.Length;
|
|
Buffer.BlockCopy(Summary, 0, bytes, i, Summary.Length); i += Summary.Length;
|
|
bytes[i++] = (byte)(Details.Length % 256);
|
|
bytes[i++] = (byte)((Details.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Details, 0, bytes, i, Details.Length); i += Details.Length;
|
|
bytes[i++] = (byte)VersionString.Length;
|
|
Buffer.BlockCopy(VersionString, 0, bytes, i, VersionString.Length); i += VersionString.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ReportData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ReportDataBlock ReportData;
|
|
|
|
public UserReportPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.UserReport;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 133;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ReportData = new ReportDataBlock();
|
|
}
|
|
|
|
public UserReportPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ReportData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public UserReportPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ReportData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ReportData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ReportData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AlertMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AlertDataBlock : PacketBlock
|
|
{
|
|
public byte[] Message;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (Message != null) { length += Message.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AlertDataBlock() { }
|
|
public AlertDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Message.Length;
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AlertInfoBlock : PacketBlock
|
|
{
|
|
public byte[] Message;
|
|
public byte[] ExtraParams;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (Message != null) { length += Message.Length; }
|
|
if (ExtraParams != null) { length += ExtraParams.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AlertInfoBlock() { }
|
|
public AlertInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
length = bytes[i++];
|
|
ExtraParams = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ExtraParams, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Message.Length;
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
bytes[i++] = (byte)ExtraParams.Length;
|
|
Buffer.BlockCopy(ExtraParams, 0, bytes, i, ExtraParams.Length); i += ExtraParams.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentInfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentInfoBlock() { }
|
|
public AgentInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AlertData.Length;
|
|
for (int j = 0; j < AlertInfo.Length; j++)
|
|
length += AlertInfo[j].Length;
|
|
for (int j = 0; j < AgentInfo.Length; j++)
|
|
length += AgentInfo[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AlertDataBlock AlertData;
|
|
public AlertInfoBlock[] AlertInfo;
|
|
public AgentInfoBlock[] AgentInfo;
|
|
|
|
public AlertMessagePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AlertMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 134;
|
|
Header.Reliable = true;
|
|
AlertData = new AlertDataBlock();
|
|
AlertInfo = null;
|
|
AgentInfo = null;
|
|
}
|
|
|
|
public AlertMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AlertData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(AlertInfo == null || AlertInfo.Length != -1) {
|
|
AlertInfo = new AlertInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AlertInfo[j] = new AlertInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AlertInfo[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AgentInfo == null || AgentInfo.Length != -1) {
|
|
AgentInfo = new AgentInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentInfo[j] = new AgentInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AlertMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AlertData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(AlertInfo == null || AlertInfo.Length != count) {
|
|
AlertInfo = new AlertInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AlertInfo[j] = new AlertInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AlertInfo[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AgentInfo == null || AgentInfo.Length != count) {
|
|
AgentInfo = new AgentInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentInfo[j] = new AgentInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AlertData.Length;
|
|
length++;
|
|
for (int j = 0; j < AlertInfo.Length; j++) { length += AlertInfo[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AgentInfo.Length; j++) { length += AgentInfo[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AlertData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AlertInfo.Length;
|
|
for (int j = 0; j < AlertInfo.Length; j++) { AlertInfo[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AgentInfo.Length;
|
|
for (int j = 0; j < AgentInfo.Length; j++) { AgentInfo[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AlertData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AlertData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int AlertInfoStart = 0;
|
|
int AgentInfoStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int AlertInfoCount = 0;
|
|
int AgentInfoCount = 0;
|
|
|
|
i = AlertInfoStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AlertInfo.Length) {
|
|
int blockLength = AlertInfo[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AlertInfoStart) {
|
|
variableLength += blockLength;
|
|
++AlertInfoCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AgentInfoStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AgentInfo.Length) {
|
|
int blockLength = AgentInfo[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AgentInfoStart) {
|
|
variableLength += blockLength;
|
|
++AgentInfoCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)AlertInfoCount;
|
|
for (i = AlertInfoStart; i < AlertInfoStart + AlertInfoCount; i++) { AlertInfo[i].ToBytes(packet, ref length); }
|
|
AlertInfoStart += AlertInfoCount;
|
|
|
|
packet[length++] = (byte)AgentInfoCount;
|
|
for (i = AgentInfoStart; i < AgentInfoStart + AgentInfoCount; i++) { AgentInfo[i].ToBytes(packet, ref length); }
|
|
AgentInfoStart += AgentInfoCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
AlertInfoStart < AlertInfo.Length ||
|
|
AgentInfoStart < AgentInfo.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentAlertMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AlertDataBlock : PacketBlock
|
|
{
|
|
public bool Modal;
|
|
public byte[] Message;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (Message != null) { length += Message.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AlertDataBlock() { }
|
|
public AlertDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
Modal = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = bytes[i++];
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((Modal) ? 1 : 0);
|
|
bytes[i++] = (byte)Message.Length;
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += AlertData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public AlertDataBlock AlertData;
|
|
|
|
public AgentAlertMessagePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentAlertMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 135;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
AlertData = new AlertDataBlock();
|
|
}
|
|
|
|
public AgentAlertMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
AlertData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentAlertMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
AlertData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += AlertData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
AlertData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MeanCollisionAlertPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class MeanCollisionBlock : PacketBlock
|
|
{
|
|
public UUID Victim;
|
|
public UUID Perp;
|
|
public uint Time;
|
|
public float Mag;
|
|
public byte Type;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 41;
|
|
}
|
|
}
|
|
|
|
public MeanCollisionBlock() { }
|
|
public MeanCollisionBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Victim.FromBytes(bytes, i); i += 16;
|
|
Perp.FromBytes(bytes, i); i += 16;
|
|
Time = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Mag = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Type = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Victim.ToBytes(bytes, i); i += 16;
|
|
Perp.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Time, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Mag, bytes, i); i += 4;
|
|
bytes[i++] = Type;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < MeanCollision.Length; j++)
|
|
length += MeanCollision[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public MeanCollisionBlock[] MeanCollision;
|
|
|
|
public MeanCollisionAlertPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.MeanCollisionAlert;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 136;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
MeanCollision = null;
|
|
}
|
|
|
|
public MeanCollisionAlertPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(MeanCollision == null || MeanCollision.Length != -1) {
|
|
MeanCollision = new MeanCollisionBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ MeanCollision[j] = new MeanCollisionBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ MeanCollision[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public MeanCollisionAlertPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(MeanCollision == null || MeanCollision.Length != count) {
|
|
MeanCollision = new MeanCollisionBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ MeanCollision[j] = new MeanCollisionBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ MeanCollision[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < MeanCollision.Length; j++) { length += MeanCollision[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)MeanCollision.Length;
|
|
for (int j = 0; j < MeanCollision.Length; j++) { MeanCollision[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int MeanCollisionStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int MeanCollisionCount = 0;
|
|
|
|
i = MeanCollisionStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < MeanCollision.Length) {
|
|
int blockLength = MeanCollision[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == MeanCollisionStart) {
|
|
variableLength += blockLength;
|
|
++MeanCollisionCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)MeanCollisionCount;
|
|
for (i = MeanCollisionStart; i < MeanCollisionStart + MeanCollisionCount; i++) { MeanCollision[i].ToBytes(packet, ref length); }
|
|
MeanCollisionStart += MeanCollisionCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
MeanCollisionStart < MeanCollision.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ViewerFrozenMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class FrozenDataBlock : PacketBlock
|
|
{
|
|
public bool Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public FrozenDataBlock() { }
|
|
public FrozenDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Data = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((Data) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += FrozenData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public FrozenDataBlock FrozenData;
|
|
|
|
public ViewerFrozenMessagePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ViewerFrozenMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 137;
|
|
Header.Reliable = true;
|
|
FrozenData = new FrozenDataBlock();
|
|
}
|
|
|
|
public ViewerFrozenMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
FrozenData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ViewerFrozenMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
FrozenData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += FrozenData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
FrozenData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class HealthMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class HealthDataBlock : PacketBlock
|
|
{
|
|
public float Health;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public HealthDataBlock() { }
|
|
public HealthDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Health = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.FloatToBytes(Health, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += HealthData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public HealthDataBlock HealthData;
|
|
|
|
public HealthMessagePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.HealthMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 138;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
HealthData = new HealthDataBlock();
|
|
}
|
|
|
|
public HealthMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
HealthData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public HealthMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
HealthData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += HealthData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
HealthData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChatFromSimulatorPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ChatDataBlock : PacketBlock
|
|
{
|
|
public byte[] FromName;
|
|
public UUID SourceID;
|
|
public UUID OwnerID;
|
|
public byte SourceType;
|
|
public byte ChatType;
|
|
public byte Audible;
|
|
public Vector3 Position;
|
|
public byte[] Message;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 50;
|
|
if (FromName != null) { length += FromName.Length; }
|
|
if (Message != null) { length += Message.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ChatDataBlock() { }
|
|
public ChatDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
FromName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, FromName, 0, length); i += length;
|
|
SourceID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
SourceType = (byte)bytes[i++];
|
|
ChatType = (byte)bytes[i++];
|
|
Audible = (byte)bytes[i++];
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)FromName.Length;
|
|
Buffer.BlockCopy(FromName, 0, bytes, i, FromName.Length); i += FromName.Length;
|
|
SourceID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = SourceType;
|
|
bytes[i++] = ChatType;
|
|
bytes[i++] = Audible;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = (byte)(Message.Length % 256);
|
|
bytes[i++] = (byte)((Message.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += ChatData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ChatDataBlock ChatData;
|
|
|
|
public ChatFromSimulatorPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ChatFromSimulator;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 139;
|
|
Header.Reliable = true;
|
|
ChatData = new ChatDataBlock();
|
|
}
|
|
|
|
public ChatFromSimulatorPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ChatData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ChatFromSimulatorPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ChatData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += ChatData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ChatData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SimStatsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class RegionBlock : PacketBlock
|
|
{
|
|
public uint RegionX;
|
|
public uint RegionY;
|
|
public uint RegionFlags;
|
|
public uint ObjectCapacity;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public RegionBlock() { }
|
|
public RegionBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionX = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RegionY = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RegionFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ObjectCapacity = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(RegionX, bytes, i); i += 4;
|
|
Utils.UIntToBytes(RegionY, bytes, i); i += 4;
|
|
Utils.UIntToBytes(RegionFlags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ObjectCapacity, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StatBlock : PacketBlock
|
|
{
|
|
public uint StatID;
|
|
public float StatValue;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public StatBlock() { }
|
|
public StatBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
StatID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
StatValue = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(StatID, bytes, i); i += 4;
|
|
Utils.FloatToBytes(StatValue, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PidStatBlock : PacketBlock
|
|
{
|
|
public int PID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public PidStatBlock() { }
|
|
public PidStatBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
PID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(PID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfoBlock : PacketBlock
|
|
{
|
|
public ulong RegionFlagsExtended;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public RegionInfoBlock() { }
|
|
public RegionInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionFlagsExtended = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionFlagsExtended, bytes, i); i += 8;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += Region.Length;
|
|
for (int j = 0; j < Stat.Length; j++)
|
|
length += Stat[j].Length;
|
|
length += PidStat.Length;
|
|
for (int j = 0; j < RegionInfo.Length; j++)
|
|
length += RegionInfo[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RegionBlock Region;
|
|
public StatBlock[] Stat;
|
|
public PidStatBlock PidStat;
|
|
public RegionInfoBlock[] RegionInfo;
|
|
|
|
public SimStatsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.SimStats;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 140;
|
|
Header.Reliable = true;
|
|
Region = new RegionBlock();
|
|
Stat = null;
|
|
PidStat = new PidStatBlock();
|
|
RegionInfo = null;
|
|
}
|
|
|
|
public SimStatsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Region.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Stat == null || Stat.Length != -1) {
|
|
Stat = new StatBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Stat[j] = new StatBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Stat[j].FromBytes(bytes, ref i); }
|
|
PidStat.FromBytes(bytes, ref i);
|
|
count = (int)bytes[i++];
|
|
if(RegionInfo == null || RegionInfo.Length != -1) {
|
|
RegionInfo = new RegionInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RegionInfo[j] = new RegionInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RegionInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public SimStatsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Region.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Stat == null || Stat.Length != count) {
|
|
Stat = new StatBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Stat[j] = new StatBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Stat[j].FromBytes(bytes, ref i); }
|
|
PidStat.FromBytes(bytes, ref i);
|
|
count = (int)bytes[i++];
|
|
if(RegionInfo == null || RegionInfo.Length != count) {
|
|
RegionInfo = new RegionInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RegionInfo[j] = new RegionInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RegionInfo[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Region.Length;
|
|
length += PidStat.Length;
|
|
length++;
|
|
for (int j = 0; j < Stat.Length; j++) { length += Stat[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < RegionInfo.Length; j++) { length += RegionInfo[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Region.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Stat.Length;
|
|
for (int j = 0; j < Stat.Length; j++) { Stat[j].ToBytes(bytes, ref i); }
|
|
PidStat.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)RegionInfo.Length;
|
|
for (int j = 0; j < RegionInfo.Length; j++) { RegionInfo[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestRegionInfoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public RequestRegionInfoPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RequestRegionInfo;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 141;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public RequestRegionInfoPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RequestRegionInfoPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfoBlock : PacketBlock
|
|
{
|
|
public byte[] SimName;
|
|
public uint EstateID;
|
|
public uint ParentEstateID;
|
|
public uint RegionFlags;
|
|
public byte SimAccess;
|
|
public byte MaxAgents;
|
|
public float BillableFactor;
|
|
public float ObjectBonusFactor;
|
|
public float WaterHeight;
|
|
public float TerrainRaiseLimit;
|
|
public float TerrainLowerLimit;
|
|
public int PricePerMeter;
|
|
public int RedirectGridX;
|
|
public int RedirectGridY;
|
|
public bool UseEstateSun;
|
|
public float SunHour;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 52;
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RegionInfoBlock() { }
|
|
public RegionInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
EstateID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ParentEstateID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RegionFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SimAccess = (byte)bytes[i++];
|
|
MaxAgents = (byte)bytes[i++];
|
|
BillableFactor = Utils.BytesToFloat(bytes, i); i += 4;
|
|
ObjectBonusFactor = Utils.BytesToFloat(bytes, i); i += 4;
|
|
WaterHeight = Utils.BytesToFloat(bytes, i); i += 4;
|
|
TerrainRaiseLimit = Utils.BytesToFloat(bytes, i); i += 4;
|
|
TerrainLowerLimit = Utils.BytesToFloat(bytes, i); i += 4;
|
|
PricePerMeter = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RedirectGridX = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RedirectGridY = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
UseEstateSun = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
SunHour = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
Utils.UIntToBytes(EstateID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ParentEstateID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(RegionFlags, bytes, i); i += 4;
|
|
bytes[i++] = SimAccess;
|
|
bytes[i++] = MaxAgents;
|
|
Utils.FloatToBytes(BillableFactor, bytes, i); i += 4;
|
|
Utils.FloatToBytes(ObjectBonusFactor, bytes, i); i += 4;
|
|
Utils.FloatToBytes(WaterHeight, bytes, i); i += 4;
|
|
Utils.FloatToBytes(TerrainRaiseLimit, bytes, i); i += 4;
|
|
Utils.FloatToBytes(TerrainLowerLimit, bytes, i); i += 4;
|
|
Utils.IntToBytes(PricePerMeter, bytes, i); i += 4;
|
|
Utils.IntToBytes(RedirectGridX, bytes, i); i += 4;
|
|
Utils.IntToBytes(RedirectGridY, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((UseEstateSun) ? 1 : 0);
|
|
Utils.FloatToBytes(SunHour, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfo2Block : PacketBlock
|
|
{
|
|
public byte[] ProductSKU;
|
|
public byte[] ProductName;
|
|
public uint MaxAgents32;
|
|
public uint HardMaxAgents;
|
|
public uint HardMaxObjects;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 14;
|
|
if (ProductSKU != null) { length += ProductSKU.Length; }
|
|
if (ProductName != null) { length += ProductName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RegionInfo2Block() { }
|
|
public RegionInfo2Block(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
ProductSKU = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ProductSKU, 0, length); i += length;
|
|
length = bytes[i++];
|
|
ProductName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ProductName, 0, length); i += length;
|
|
MaxAgents32 = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
HardMaxAgents = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
HardMaxObjects = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)ProductSKU.Length;
|
|
Buffer.BlockCopy(ProductSKU, 0, bytes, i, ProductSKU.Length); i += ProductSKU.Length;
|
|
bytes[i++] = (byte)ProductName.Length;
|
|
Buffer.BlockCopy(ProductName, 0, bytes, i, ProductName.Length); i += ProductName.Length;
|
|
Utils.UIntToBytes(MaxAgents32, bytes, i); i += 4;
|
|
Utils.UIntToBytes(HardMaxAgents, bytes, i); i += 4;
|
|
Utils.UIntToBytes(HardMaxObjects, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfo3Block : PacketBlock
|
|
{
|
|
public ulong RegionFlagsExtended;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public RegionInfo3Block() { }
|
|
public RegionInfo3Block(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionFlagsExtended = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionFlagsExtended, bytes, i); i += 8;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfo5Block : PacketBlock
|
|
{
|
|
public float ChatWhisperRange;
|
|
public float ChatNormalRange;
|
|
public float ChatShoutRange;
|
|
public float ChatWhisperOffset;
|
|
public float ChatNormalOffset;
|
|
public float ChatShoutOffset;
|
|
public uint ChatFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 28;
|
|
}
|
|
}
|
|
|
|
public RegionInfo5Block() { }
|
|
public RegionInfo5Block(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ChatWhisperRange = Utils.BytesToFloat(bytes, i); i += 4;
|
|
ChatNormalRange = Utils.BytesToFloat(bytes, i); i += 4;
|
|
ChatShoutRange = Utils.BytesToFloat(bytes, i); i += 4;
|
|
ChatWhisperOffset = Utils.BytesToFloat(bytes, i); i += 4;
|
|
ChatNormalOffset = Utils.BytesToFloat(bytes, i); i += 4;
|
|
ChatShoutOffset = Utils.BytesToFloat(bytes, i); i += 4;
|
|
ChatFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.FloatToBytes(ChatWhisperRange, bytes, i); i += 4;
|
|
Utils.FloatToBytes(ChatNormalRange, bytes, i); i += 4;
|
|
Utils.FloatToBytes(ChatShoutRange, bytes, i); i += 4;
|
|
Utils.FloatToBytes(ChatWhisperOffset, bytes, i); i += 4;
|
|
Utils.FloatToBytes(ChatNormalOffset, bytes, i); i += 4;
|
|
Utils.FloatToBytes(ChatShoutOffset, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ChatFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
length += RegionInfo.Length;
|
|
length += RegionInfo2.Length;
|
|
for (int j = 0; j < RegionInfo3.Length; j++)
|
|
length += RegionInfo3[j].Length;
|
|
for (int j = 0; j < RegionInfo5.Length; j++)
|
|
length += RegionInfo5[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RegionInfoBlock RegionInfo;
|
|
public RegionInfo2Block RegionInfo2;
|
|
public RegionInfo3Block[] RegionInfo3;
|
|
public RegionInfo5Block[] RegionInfo5;
|
|
|
|
public RegionInfoPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.RegionInfo;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 142;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
RegionInfo = new RegionInfoBlock();
|
|
RegionInfo2 = new RegionInfo2Block();
|
|
RegionInfo3 = null;
|
|
RegionInfo5 = null;
|
|
}
|
|
|
|
public RegionInfoPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RegionInfo.FromBytes(bytes, ref i);
|
|
RegionInfo2.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RegionInfo3 == null || RegionInfo3.Length != -1) {
|
|
RegionInfo3 = new RegionInfo3Block[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RegionInfo3[j] = new RegionInfo3Block(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RegionInfo3[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(RegionInfo5 == null || RegionInfo5.Length != -1) {
|
|
RegionInfo5 = new RegionInfo5Block[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RegionInfo5[j] = new RegionInfo5Block(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RegionInfo5[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public RegionInfoPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RegionInfo.FromBytes(bytes, ref i);
|
|
RegionInfo2.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RegionInfo3 == null || RegionInfo3.Length != count) {
|
|
RegionInfo3 = new RegionInfo3Block[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RegionInfo3[j] = new RegionInfo3Block(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RegionInfo3[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(RegionInfo5 == null || RegionInfo5.Length != count) {
|
|
RegionInfo5 = new RegionInfo5Block[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RegionInfo5[j] = new RegionInfo5Block(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RegionInfo5[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RegionInfo.Length;
|
|
length += RegionInfo2.Length;
|
|
length++;
|
|
for (int j = 0; j < RegionInfo3.Length; j++) { length += RegionInfo3[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < RegionInfo5.Length; j++) { length += RegionInfo5[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
RegionInfo.ToBytes(bytes, ref i);
|
|
RegionInfo2.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)RegionInfo3.Length;
|
|
for (int j = 0; j < RegionInfo3.Length; j++) { RegionInfo3[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)RegionInfo5.Length;
|
|
for (int j = 0; j < RegionInfo5.Length; j++) { RegionInfo5[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += RegionInfo.Length;
|
|
fixedLength += RegionInfo2.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
RegionInfo.ToBytes(fixedBytes, ref i);
|
|
RegionInfo2.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int RegionInfo3Start = 0;
|
|
int RegionInfo5Start = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int RegionInfo3Count = 0;
|
|
int RegionInfo5Count = 0;
|
|
|
|
i = RegionInfo3Start;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < RegionInfo3.Length) {
|
|
int blockLength = RegionInfo3[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == RegionInfo3Start) {
|
|
variableLength += blockLength;
|
|
++RegionInfo3Count;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = RegionInfo5Start;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < RegionInfo5.Length) {
|
|
int blockLength = RegionInfo5[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == RegionInfo5Start) {
|
|
variableLength += blockLength;
|
|
++RegionInfo5Count;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)RegionInfo3Count;
|
|
for (i = RegionInfo3Start; i < RegionInfo3Start + RegionInfo3Count; i++) { RegionInfo3[i].ToBytes(packet, ref length); }
|
|
RegionInfo3Start += RegionInfo3Count;
|
|
|
|
packet[length++] = (byte)RegionInfo5Count;
|
|
for (i = RegionInfo5Start; i < RegionInfo5Start + RegionInfo5Count; i++) { RegionInfo5[i].ToBytes(packet, ref length); }
|
|
RegionInfo5Start += RegionInfo5Count;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
RegionInfo3Start < RegionInfo3.Length ||
|
|
RegionInfo5Start < RegionInfo5.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GodUpdateRegionInfoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfoBlock : PacketBlock
|
|
{
|
|
public byte[] SimName;
|
|
public uint EstateID;
|
|
public uint ParentEstateID;
|
|
public uint RegionFlags;
|
|
public float BillableFactor;
|
|
public int PricePerMeter;
|
|
public int RedirectGridX;
|
|
public int RedirectGridY;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 29;
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RegionInfoBlock() { }
|
|
public RegionInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
EstateID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ParentEstateID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RegionFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
BillableFactor = Utils.BytesToFloat(bytes, i); i += 4;
|
|
PricePerMeter = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RedirectGridX = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RedirectGridY = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
Utils.UIntToBytes(EstateID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ParentEstateID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(RegionFlags, bytes, i); i += 4;
|
|
Utils.FloatToBytes(BillableFactor, bytes, i); i += 4;
|
|
Utils.IntToBytes(PricePerMeter, bytes, i); i += 4;
|
|
Utils.IntToBytes(RedirectGridX, bytes, i); i += 4;
|
|
Utils.IntToBytes(RedirectGridY, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfo2Block : PacketBlock
|
|
{
|
|
public ulong RegionFlagsExtended;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public RegionInfo2Block() { }
|
|
public RegionInfo2Block(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionFlagsExtended = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionFlagsExtended, bytes, i); i += 8;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += RegionInfo.Length;
|
|
for (int j = 0; j < RegionInfo2.Length; j++)
|
|
length += RegionInfo2[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RegionInfoBlock RegionInfo;
|
|
public RegionInfo2Block[] RegionInfo2;
|
|
|
|
public GodUpdateRegionInfoPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GodUpdateRegionInfo;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 143;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
RegionInfo = new RegionInfoBlock();
|
|
RegionInfo2 = null;
|
|
}
|
|
|
|
public GodUpdateRegionInfoPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RegionInfo.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RegionInfo2 == null || RegionInfo2.Length != -1) {
|
|
RegionInfo2 = new RegionInfo2Block[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RegionInfo2[j] = new RegionInfo2Block(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RegionInfo2[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GodUpdateRegionInfoPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RegionInfo.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RegionInfo2 == null || RegionInfo2.Length != count) {
|
|
RegionInfo2 = new RegionInfo2Block[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RegionInfo2[j] = new RegionInfo2Block(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RegionInfo2[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RegionInfo.Length;
|
|
length++;
|
|
for (int j = 0; j < RegionInfo2.Length; j++) { length += RegionInfo2[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
RegionInfo.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)RegionInfo2.Length;
|
|
for (int j = 0; j < RegionInfo2.Length; j++) { RegionInfo2[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += RegionInfo.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
RegionInfo.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int RegionInfo2Start = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int RegionInfo2Count = 0;
|
|
|
|
i = RegionInfo2Start;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < RegionInfo2.Length) {
|
|
int blockLength = RegionInfo2[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == RegionInfo2Start) {
|
|
variableLength += blockLength;
|
|
++RegionInfo2Count;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)RegionInfo2Count;
|
|
for (i = RegionInfo2Start; i < RegionInfo2Start + RegionInfo2Count; i++) { RegionInfo2[i].ToBytes(packet, ref length); }
|
|
RegionInfo2Start += RegionInfo2Count;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
RegionInfo2Start < RegionInfo2.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionHandshakePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class RegionInfoBlock : PacketBlock
|
|
{
|
|
public uint RegionFlags;
|
|
public byte SimAccess;
|
|
public byte[] SimName;
|
|
public UUID SimOwner;
|
|
public bool IsEstateManager;
|
|
public float WaterHeight;
|
|
public float BillableFactor;
|
|
public UUID CacheID;
|
|
public UUID TerrainBase0;
|
|
public UUID TerrainBase1;
|
|
public UUID TerrainBase2;
|
|
public UUID TerrainBase3;
|
|
public UUID TerrainDetail0;
|
|
public UUID TerrainDetail1;
|
|
public UUID TerrainDetail2;
|
|
public UUID TerrainDetail3;
|
|
public float TerrainStartHeight00;
|
|
public float TerrainStartHeight01;
|
|
public float TerrainStartHeight10;
|
|
public float TerrainStartHeight11;
|
|
public float TerrainHeightRange00;
|
|
public float TerrainHeightRange01;
|
|
public float TerrainHeightRange10;
|
|
public float TerrainHeightRange11;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 207;
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RegionInfoBlock() { }
|
|
public RegionInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
RegionFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SimAccess = (byte)bytes[i++];
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
SimOwner.FromBytes(bytes, i); i += 16;
|
|
IsEstateManager = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
WaterHeight = Utils.BytesToFloat(bytes, i); i += 4;
|
|
BillableFactor = Utils.BytesToFloat(bytes, i); i += 4;
|
|
CacheID.FromBytes(bytes, i); i += 16;
|
|
TerrainBase0.FromBytes(bytes, i); i += 16;
|
|
TerrainBase1.FromBytes(bytes, i); i += 16;
|
|
TerrainBase2.FromBytes(bytes, i); i += 16;
|
|
TerrainBase3.FromBytes(bytes, i); i += 16;
|
|
TerrainDetail0.FromBytes(bytes, i); i += 16;
|
|
TerrainDetail1.FromBytes(bytes, i); i += 16;
|
|
TerrainDetail2.FromBytes(bytes, i); i += 16;
|
|
TerrainDetail3.FromBytes(bytes, i); i += 16;
|
|
TerrainStartHeight00 = Utils.BytesToFloat(bytes, i); i += 4;
|
|
TerrainStartHeight01 = Utils.BytesToFloat(bytes, i); i += 4;
|
|
TerrainStartHeight10 = Utils.BytesToFloat(bytes, i); i += 4;
|
|
TerrainStartHeight11 = Utils.BytesToFloat(bytes, i); i += 4;
|
|
TerrainHeightRange00 = Utils.BytesToFloat(bytes, i); i += 4;
|
|
TerrainHeightRange01 = Utils.BytesToFloat(bytes, i); i += 4;
|
|
TerrainHeightRange10 = Utils.BytesToFloat(bytes, i); i += 4;
|
|
TerrainHeightRange11 = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(RegionFlags, bytes, i); i += 4;
|
|
bytes[i++] = SimAccess;
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
SimOwner.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsEstateManager) ? 1 : 0);
|
|
Utils.FloatToBytes(WaterHeight, bytes, i); i += 4;
|
|
Utils.FloatToBytes(BillableFactor, bytes, i); i += 4;
|
|
CacheID.ToBytes(bytes, i); i += 16;
|
|
TerrainBase0.ToBytes(bytes, i); i += 16;
|
|
TerrainBase1.ToBytes(bytes, i); i += 16;
|
|
TerrainBase2.ToBytes(bytes, i); i += 16;
|
|
TerrainBase3.ToBytes(bytes, i); i += 16;
|
|
TerrainDetail0.ToBytes(bytes, i); i += 16;
|
|
TerrainDetail1.ToBytes(bytes, i); i += 16;
|
|
TerrainDetail2.ToBytes(bytes, i); i += 16;
|
|
TerrainDetail3.ToBytes(bytes, i); i += 16;
|
|
Utils.FloatToBytes(TerrainStartHeight00, bytes, i); i += 4;
|
|
Utils.FloatToBytes(TerrainStartHeight01, bytes, i); i += 4;
|
|
Utils.FloatToBytes(TerrainStartHeight10, bytes, i); i += 4;
|
|
Utils.FloatToBytes(TerrainStartHeight11, bytes, i); i += 4;
|
|
Utils.FloatToBytes(TerrainHeightRange00, bytes, i); i += 4;
|
|
Utils.FloatToBytes(TerrainHeightRange01, bytes, i); i += 4;
|
|
Utils.FloatToBytes(TerrainHeightRange10, bytes, i); i += 4;
|
|
Utils.FloatToBytes(TerrainHeightRange11, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfo2Block : PacketBlock
|
|
{
|
|
public UUID RegionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public RegionInfo2Block() { }
|
|
public RegionInfo2Block(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RegionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfo3Block : PacketBlock
|
|
{
|
|
public int CPUClassID;
|
|
public int CPURatio;
|
|
public byte[] ColoName;
|
|
public byte[] ProductSKU;
|
|
public byte[] ProductName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
if (ColoName != null) { length += ColoName.Length; }
|
|
if (ProductSKU != null) { length += ProductSKU.Length; }
|
|
if (ProductName != null) { length += ProductName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RegionInfo3Block() { }
|
|
public RegionInfo3Block(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
CPUClassID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CPURatio = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
ColoName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ColoName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
ProductSKU = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ProductSKU, 0, length); i += length;
|
|
length = bytes[i++];
|
|
ProductName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ProductName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(CPUClassID, bytes, i); i += 4;
|
|
Utils.IntToBytes(CPURatio, bytes, i); i += 4;
|
|
bytes[i++] = (byte)ColoName.Length;
|
|
Buffer.BlockCopy(ColoName, 0, bytes, i, ColoName.Length); i += ColoName.Length;
|
|
bytes[i++] = (byte)ProductSKU.Length;
|
|
Buffer.BlockCopy(ProductSKU, 0, bytes, i, ProductSKU.Length); i += ProductSKU.Length;
|
|
bytes[i++] = (byte)ProductName.Length;
|
|
Buffer.BlockCopy(ProductName, 0, bytes, i, ProductName.Length); i += ProductName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfo4Block : PacketBlock
|
|
{
|
|
public ulong RegionFlagsExtended;
|
|
public ulong RegionProtocols;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public RegionInfo4Block() { }
|
|
public RegionInfo4Block(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionFlagsExtended = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
RegionProtocols = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionFlagsExtended, bytes, i); i += 8;
|
|
Utils.UInt64ToBytes(RegionProtocols, bytes, i); i += 8;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += RegionInfo.Length;
|
|
length += RegionInfo2.Length;
|
|
length += RegionInfo3.Length;
|
|
for (int j = 0; j < RegionInfo4.Length; j++)
|
|
length += RegionInfo4[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RegionInfoBlock RegionInfo;
|
|
public RegionInfo2Block RegionInfo2;
|
|
public RegionInfo3Block RegionInfo3;
|
|
public RegionInfo4Block[] RegionInfo4;
|
|
|
|
public RegionHandshakePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.RegionHandshake;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 148;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
RegionInfo = new RegionInfoBlock();
|
|
RegionInfo2 = new RegionInfo2Block();
|
|
RegionInfo3 = new RegionInfo3Block();
|
|
RegionInfo4 = null;
|
|
}
|
|
|
|
public RegionHandshakePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
RegionInfo.FromBytes(bytes, ref i);
|
|
RegionInfo2.FromBytes(bytes, ref i);
|
|
RegionInfo3.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RegionInfo4 == null || RegionInfo4.Length != -1) {
|
|
RegionInfo4 = new RegionInfo4Block[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RegionInfo4[j] = new RegionInfo4Block(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RegionInfo4[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public RegionHandshakePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
RegionInfo.FromBytes(bytes, ref i);
|
|
RegionInfo2.FromBytes(bytes, ref i);
|
|
RegionInfo3.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RegionInfo4 == null || RegionInfo4.Length != count) {
|
|
RegionInfo4 = new RegionInfo4Block[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RegionInfo4[j] = new RegionInfo4Block(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RegionInfo4[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += RegionInfo.Length;
|
|
length += RegionInfo2.Length;
|
|
length += RegionInfo3.Length;
|
|
length++;
|
|
for (int j = 0; j < RegionInfo4.Length; j++) { length += RegionInfo4[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RegionInfo.ToBytes(bytes, ref i);
|
|
RegionInfo2.ToBytes(bytes, ref i);
|
|
RegionInfo3.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)RegionInfo4.Length;
|
|
for (int j = 0; j < RegionInfo4.Length; j++) { RegionInfo4[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += RegionInfo.Length;
|
|
fixedLength += RegionInfo2.Length;
|
|
fixedLength += RegionInfo3.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
RegionInfo.ToBytes(fixedBytes, ref i);
|
|
RegionInfo2.ToBytes(fixedBytes, ref i);
|
|
RegionInfo3.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int RegionInfo4Start = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int RegionInfo4Count = 0;
|
|
|
|
i = RegionInfo4Start;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < RegionInfo4.Length) {
|
|
int blockLength = RegionInfo4[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == RegionInfo4Start) {
|
|
variableLength += blockLength;
|
|
++RegionInfo4Count;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)RegionInfo4Count;
|
|
for (i = RegionInfo4Start; i < RegionInfo4Start + RegionInfo4Count; i++) { RegionInfo4[i].ToBytes(packet, ref length); }
|
|
RegionInfo4Start += RegionInfo4Count;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
RegionInfo4Start < RegionInfo4.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionHandshakeReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionInfoBlock : PacketBlock
|
|
{
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public RegionInfoBlock() { }
|
|
public RegionInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RegionInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RegionInfoBlock RegionInfo;
|
|
|
|
public RegionHandshakeReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RegionHandshakeReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 149;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
RegionInfo = new RegionInfoBlock();
|
|
}
|
|
|
|
public RegionHandshakeReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RegionInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RegionHandshakeReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RegionInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RegionInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
RegionInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SimulatorViewerTimeMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class TimeInfoBlock : PacketBlock
|
|
{
|
|
public ulong UsecSinceStart;
|
|
public uint SecPerDay;
|
|
public uint SecPerYear;
|
|
public Vector3 SunDirection;
|
|
public float SunPhase;
|
|
public Vector3 SunAngVelocity;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 44;
|
|
}
|
|
}
|
|
|
|
public TimeInfoBlock() { }
|
|
public TimeInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
UsecSinceStart = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
SecPerDay = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SecPerYear = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SunDirection.FromBytes(bytes, i); i += 12;
|
|
SunPhase = Utils.BytesToFloat(bytes, i); i += 4;
|
|
SunAngVelocity.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(UsecSinceStart, bytes, i); i += 8;
|
|
Utils.UIntToBytes(SecPerDay, bytes, i); i += 4;
|
|
Utils.UIntToBytes(SecPerYear, bytes, i); i += 4;
|
|
SunDirection.ToBytes(bytes, i); i += 12;
|
|
Utils.FloatToBytes(SunPhase, bytes, i); i += 4;
|
|
SunAngVelocity.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += TimeInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TimeInfoBlock TimeInfo;
|
|
|
|
public SimulatorViewerTimeMessagePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SimulatorViewerTimeMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 150;
|
|
Header.Reliable = true;
|
|
TimeInfo = new TimeInfoBlock();
|
|
}
|
|
|
|
public SimulatorViewerTimeMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TimeInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SimulatorViewerTimeMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TimeInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TimeInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TimeInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EnableSimulatorPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class SimulatorInfoBlock : PacketBlock
|
|
{
|
|
public ulong Handle;
|
|
public uint IP;
|
|
public ushort Port;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 14;
|
|
}
|
|
}
|
|
|
|
public SimulatorInfoBlock() { }
|
|
public SimulatorInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Handle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
IP = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Port = (ushort)((bytes[i++] << 8) + bytes[i++]);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(Handle, bytes, i); i += 8;
|
|
Utils.UIntToBytes(IP, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((Port >> 8) % 256);
|
|
bytes[i++] = (byte)(Port % 256);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += SimulatorInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public SimulatorInfoBlock SimulatorInfo;
|
|
|
|
public EnableSimulatorPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EnableSimulator;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 151;
|
|
Header.Reliable = true;
|
|
SimulatorInfo = new SimulatorInfoBlock();
|
|
}
|
|
|
|
public EnableSimulatorPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
SimulatorInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EnableSimulatorPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
SimulatorInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += SimulatorInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
SimulatorInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DisableSimulatorPacket : Packet
|
|
{
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DisableSimulatorPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DisableSimulator;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 152;
|
|
Header.Reliable = true;
|
|
}
|
|
|
|
public DisableSimulatorPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
}
|
|
|
|
public DisableSimulatorPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransferRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class TransferInfoBlock : PacketBlock
|
|
{
|
|
public UUID TransferID;
|
|
public int ChannelType;
|
|
public int SourceType;
|
|
public float Priority;
|
|
public byte[] Params;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 30;
|
|
if (Params != null) { length += Params.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public TransferInfoBlock() { }
|
|
public TransferInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TransferID.FromBytes(bytes, i); i += 16;
|
|
ChannelType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SourceType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Priority = Utils.BytesToFloat(bytes, i); i += 4;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Params = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Params, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransferID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(ChannelType, bytes, i); i += 4;
|
|
Utils.IntToBytes(SourceType, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Priority, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(Params.Length % 256);
|
|
bytes[i++] = (byte)((Params.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Params, 0, bytes, i, Params.Length); i += Params.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += TransferInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TransferInfoBlock TransferInfo;
|
|
|
|
public TransferRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TransferRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 153;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
TransferInfo = new TransferInfoBlock();
|
|
}
|
|
|
|
public TransferRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TransferInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TransferRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TransferInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TransferInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TransferInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransferInfoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class TransferInfoBlock : PacketBlock
|
|
{
|
|
public UUID TransferID;
|
|
public int ChannelType;
|
|
public int TargetType;
|
|
public int Status;
|
|
public int Size;
|
|
public byte[] Params;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 34;
|
|
if (Params != null) { length += Params.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public TransferInfoBlock() { }
|
|
public TransferInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TransferID.FromBytes(bytes, i); i += 16;
|
|
ChannelType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TargetType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Status = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Size = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Params = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Params, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransferID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(ChannelType, bytes, i); i += 4;
|
|
Utils.IntToBytes(TargetType, bytes, i); i += 4;
|
|
Utils.IntToBytes(Status, bytes, i); i += 4;
|
|
Utils.IntToBytes(Size, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(Params.Length % 256);
|
|
bytes[i++] = (byte)((Params.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Params, 0, bytes, i, Params.Length); i += Params.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += TransferInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TransferInfoBlock TransferInfo;
|
|
|
|
public TransferInfoPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TransferInfo;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 154;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
TransferInfo = new TransferInfoBlock();
|
|
}
|
|
|
|
public TransferInfoPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TransferInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TransferInfoPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TransferInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TransferInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TransferInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransferAbortPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class TransferInfoBlock : PacketBlock
|
|
{
|
|
public UUID TransferID;
|
|
public int ChannelType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public TransferInfoBlock() { }
|
|
public TransferInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransferID.FromBytes(bytes, i); i += 16;
|
|
ChannelType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransferID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(ChannelType, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += TransferInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TransferInfoBlock TransferInfo;
|
|
|
|
public TransferAbortPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TransferAbort;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 155;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
TransferInfo = new TransferInfoBlock();
|
|
}
|
|
|
|
public TransferAbortPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TransferInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TransferAbortPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TransferInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TransferInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TransferInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestXferPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class XferIDBlock : PacketBlock
|
|
{
|
|
public ulong ID;
|
|
public byte[] Filename;
|
|
public byte FilePath;
|
|
public bool DeleteOnCompletion;
|
|
public bool UseBigPackets;
|
|
public UUID VFileID;
|
|
public short VFileType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 30;
|
|
if (Filename != null) { length += Filename.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public XferIDBlock() { }
|
|
public XferIDBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ID = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
length = bytes[i++];
|
|
Filename = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Filename, 0, length); i += length;
|
|
FilePath = (byte)bytes[i++];
|
|
DeleteOnCompletion = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
UseBigPackets = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
VFileID.FromBytes(bytes, i); i += 16;
|
|
VFileType = (short)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(ID, bytes, i); i += 8;
|
|
bytes[i++] = (byte)Filename.Length;
|
|
Buffer.BlockCopy(Filename, 0, bytes, i, Filename.Length); i += Filename.Length;
|
|
bytes[i++] = FilePath;
|
|
bytes[i++] = (byte)((DeleteOnCompletion) ? 1 : 0);
|
|
bytes[i++] = (byte)((UseBigPackets) ? 1 : 0);
|
|
VFileID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)(VFileType % 256);
|
|
bytes[i++] = (byte)((VFileType >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += XferID.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public XferIDBlock XferID;
|
|
|
|
public RequestXferPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RequestXfer;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 156;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
XferID = new XferIDBlock();
|
|
}
|
|
|
|
public RequestXferPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
XferID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RequestXferPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
XferID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += XferID.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
XferID.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AbortXferPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class XferIDBlock : PacketBlock
|
|
{
|
|
public ulong ID;
|
|
public int Result;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public XferIDBlock() { }
|
|
public XferIDBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
Result = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(ID, bytes, i); i += 8;
|
|
Utils.IntToBytes(Result, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += XferID.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public XferIDBlock XferID;
|
|
|
|
public AbortXferPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AbortXfer;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 157;
|
|
Header.Reliable = true;
|
|
XferID = new XferIDBlock();
|
|
}
|
|
|
|
public AbortXferPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
XferID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AbortXferPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
XferID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += XferID.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
XferID.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarAppearancePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class SenderBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public bool IsTrial;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public SenderBlock() { }
|
|
public SenderBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
IsTrial = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsTrial) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public byte[] TextureEntry;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (TextureEntry != null) { length += TextureEntry.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
TextureEntry = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TextureEntry, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(TextureEntry.Length % 256);
|
|
bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256);
|
|
Buffer.BlockCopy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class VisualParamBlock : PacketBlock
|
|
{
|
|
public byte ParamValue;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public VisualParamBlock() { }
|
|
public VisualParamBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ParamValue = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = ParamValue;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AppearanceDataBlock : PacketBlock
|
|
{
|
|
public byte AppearanceVersion;
|
|
public int CofVersion;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 9;
|
|
}
|
|
}
|
|
|
|
public AppearanceDataBlock() { }
|
|
public AppearanceDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AppearanceVersion = (byte)bytes[i++];
|
|
CofVersion = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = AppearanceVersion;
|
|
Utils.IntToBytes(CofVersion, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AppearanceHoverBlock : PacketBlock
|
|
{
|
|
public Vector3 HoverHeight;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public AppearanceHoverBlock() { }
|
|
public AppearanceHoverBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
HoverHeight.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
HoverHeight.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AttachmentBlockBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public byte AttachmentPoint;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public AttachmentBlockBlock() { }
|
|
public AttachmentBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
AttachmentPoint = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = AttachmentPoint;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 14;
|
|
length += Sender.Length;
|
|
length += ObjectData.Length;
|
|
for (int j = 0; j < VisualParam.Length; j++)
|
|
length += VisualParam[j].Length;
|
|
for (int j = 0; j < AppearanceData.Length; j++)
|
|
length += AppearanceData[j].Length;
|
|
for (int j = 0; j < AppearanceHover.Length; j++)
|
|
length += AppearanceHover[j].Length;
|
|
for (int j = 0; j < AttachmentBlock.Length; j++)
|
|
length += AttachmentBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public SenderBlock Sender;
|
|
public ObjectDataBlock ObjectData;
|
|
public VisualParamBlock[] VisualParam;
|
|
public AppearanceDataBlock[] AppearanceData;
|
|
public AppearanceHoverBlock[] AppearanceHover;
|
|
public AttachmentBlockBlock[] AttachmentBlock;
|
|
|
|
public AvatarAppearancePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AvatarAppearance;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 158;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
Sender = new SenderBlock();
|
|
ObjectData = new ObjectDataBlock();
|
|
VisualParam = null;
|
|
AppearanceData = null;
|
|
AppearanceHover = null;
|
|
AttachmentBlock = null;
|
|
}
|
|
|
|
public AvatarAppearancePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Sender.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(VisualParam == null || VisualParam.Length != -1) {
|
|
VisualParam = new VisualParamBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ VisualParam[j] = new VisualParamBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ VisualParam[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AppearanceData == null || AppearanceData.Length != -1) {
|
|
AppearanceData = new AppearanceDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AppearanceData[j] = new AppearanceDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AppearanceData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AppearanceHover == null || AppearanceHover.Length != -1) {
|
|
AppearanceHover = new AppearanceHoverBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AppearanceHover[j] = new AppearanceHoverBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AppearanceHover[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AttachmentBlock == null || AttachmentBlock.Length != -1) {
|
|
AttachmentBlock = new AttachmentBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AttachmentBlock[j] = new AttachmentBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AttachmentBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AvatarAppearancePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Sender.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(VisualParam == null || VisualParam.Length != count) {
|
|
VisualParam = new VisualParamBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ VisualParam[j] = new VisualParamBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ VisualParam[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AppearanceData == null || AppearanceData.Length != count) {
|
|
AppearanceData = new AppearanceDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AppearanceData[j] = new AppearanceDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AppearanceData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AppearanceHover == null || AppearanceHover.Length != count) {
|
|
AppearanceHover = new AppearanceHoverBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AppearanceHover[j] = new AppearanceHoverBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AppearanceHover[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AttachmentBlock == null || AttachmentBlock.Length != count) {
|
|
AttachmentBlock = new AttachmentBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AttachmentBlock[j] = new AttachmentBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AttachmentBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Sender.Length;
|
|
length += ObjectData.Length;
|
|
length++;
|
|
for (int j = 0; j < VisualParam.Length; j++) { length += VisualParam[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AppearanceData.Length; j++) { length += AppearanceData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AppearanceHover.Length; j++) { length += AppearanceHover[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AttachmentBlock.Length; j++) { length += AttachmentBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Sender.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)VisualParam.Length;
|
|
for (int j = 0; j < VisualParam.Length; j++) { VisualParam[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AppearanceData.Length;
|
|
for (int j = 0; j < AppearanceData.Length; j++) { AppearanceData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AppearanceHover.Length;
|
|
for (int j = 0; j < AppearanceHover.Length; j++) { AppearanceHover[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AttachmentBlock.Length;
|
|
for (int j = 0; j < AttachmentBlock.Length; j++) { AttachmentBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += Sender.Length;
|
|
fixedLength += ObjectData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
Sender.ToBytes(fixedBytes, ref i);
|
|
ObjectData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 4;
|
|
|
|
int VisualParamStart = 0;
|
|
int AppearanceDataStart = 0;
|
|
int AppearanceHoverStart = 0;
|
|
int AttachmentBlockStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int VisualParamCount = 0;
|
|
int AppearanceDataCount = 0;
|
|
int AppearanceHoverCount = 0;
|
|
int AttachmentBlockCount = 0;
|
|
|
|
i = VisualParamStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < VisualParam.Length) {
|
|
int blockLength = VisualParam[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == VisualParamStart) {
|
|
variableLength += blockLength;
|
|
++VisualParamCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AppearanceDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AppearanceData.Length) {
|
|
int blockLength = AppearanceData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AppearanceDataStart) {
|
|
variableLength += blockLength;
|
|
++AppearanceDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AppearanceHoverStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AppearanceHover.Length) {
|
|
int blockLength = AppearanceHover[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AppearanceHoverStart) {
|
|
variableLength += blockLength;
|
|
++AppearanceHoverCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AttachmentBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AttachmentBlock.Length) {
|
|
int blockLength = AttachmentBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AttachmentBlockStart) {
|
|
variableLength += blockLength;
|
|
++AttachmentBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)VisualParamCount;
|
|
for (i = VisualParamStart; i < VisualParamStart + VisualParamCount; i++) { VisualParam[i].ToBytes(packet, ref length); }
|
|
VisualParamStart += VisualParamCount;
|
|
|
|
packet[length++] = (byte)AppearanceDataCount;
|
|
for (i = AppearanceDataStart; i < AppearanceDataStart + AppearanceDataCount; i++) { AppearanceData[i].ToBytes(packet, ref length); }
|
|
AppearanceDataStart += AppearanceDataCount;
|
|
|
|
packet[length++] = (byte)AppearanceHoverCount;
|
|
for (i = AppearanceHoverStart; i < AppearanceHoverStart + AppearanceHoverCount; i++) { AppearanceHover[i].ToBytes(packet, ref length); }
|
|
AppearanceHoverStart += AppearanceHoverCount;
|
|
|
|
packet[length++] = (byte)AttachmentBlockCount;
|
|
for (i = AttachmentBlockStart; i < AttachmentBlockStart + AttachmentBlockCount; i++) { AttachmentBlock[i].ToBytes(packet, ref length); }
|
|
AttachmentBlockStart += AttachmentBlockCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
VisualParamStart < VisualParam.Length ||
|
|
AppearanceDataStart < AppearanceData.Length ||
|
|
AppearanceHoverStart < AppearanceHover.Length ||
|
|
AttachmentBlockStart < AttachmentBlock.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SetFollowCamPropertiesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CameraPropertyBlock : PacketBlock
|
|
{
|
|
public int Type;
|
|
public float Value;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public CameraPropertyBlock() { }
|
|
public CameraPropertyBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Type = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Value = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(Type, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Value, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += ObjectData.Length;
|
|
for (int j = 0; j < CameraProperty.Length; j++)
|
|
length += CameraProperty[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ObjectDataBlock ObjectData;
|
|
public CameraPropertyBlock[] CameraProperty;
|
|
|
|
public SetFollowCamPropertiesPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.SetFollowCamProperties;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 159;
|
|
Header.Reliable = true;
|
|
ObjectData = new ObjectDataBlock();
|
|
CameraProperty = null;
|
|
}
|
|
|
|
public SetFollowCamPropertiesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(CameraProperty == null || CameraProperty.Length != -1) {
|
|
CameraProperty = new CameraPropertyBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ CameraProperty[j] = new CameraPropertyBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ CameraProperty[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public SetFollowCamPropertiesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(CameraProperty == null || CameraProperty.Length != count) {
|
|
CameraProperty = new CameraPropertyBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ CameraProperty[j] = new CameraPropertyBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ CameraProperty[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += ObjectData.Length;
|
|
length++;
|
|
for (int j = 0; j < CameraProperty.Length; j++) { length += CameraProperty[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)CameraProperty.Length;
|
|
for (int j = 0; j < CameraProperty.Length; j++) { CameraProperty[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += ObjectData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
ObjectData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int CameraPropertyStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int CameraPropertyCount = 0;
|
|
|
|
i = CameraPropertyStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < CameraProperty.Length) {
|
|
int blockLength = CameraProperty[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == CameraPropertyStart) {
|
|
variableLength += blockLength;
|
|
++CameraPropertyCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)CameraPropertyCount;
|
|
for (i = CameraPropertyStart; i < CameraPropertyStart + CameraPropertyCount; i++) { CameraProperty[i].ToBytes(packet, ref length); }
|
|
CameraPropertyStart += CameraPropertyCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
CameraPropertyStart < CameraProperty.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ClearFollowCamPropertiesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += ObjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ObjectDataBlock ObjectData;
|
|
|
|
public ClearFollowCamPropertiesPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ClearFollowCamProperties;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 160;
|
|
Header.Reliable = true;
|
|
ObjectData = new ObjectDataBlock();
|
|
}
|
|
|
|
public ClearFollowCamPropertiesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ClearFollowCamPropertiesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += ObjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestPayPricePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += ObjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ObjectDataBlock ObjectData;
|
|
|
|
public RequestPayPricePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RequestPayPrice;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 161;
|
|
Header.Reliable = true;
|
|
ObjectData = new ObjectDataBlock();
|
|
}
|
|
|
|
public RequestPayPricePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RequestPayPricePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += ObjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PayPriceReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public int DefaultPayPrice;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
DefaultPayPrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(DefaultPayPrice, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ButtonDataBlock : PacketBlock
|
|
{
|
|
public int PayButton;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ButtonDataBlock() { }
|
|
public ButtonDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
PayButton = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(PayButton, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += ObjectData.Length;
|
|
for (int j = 0; j < ButtonData.Length; j++)
|
|
length += ButtonData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ObjectDataBlock ObjectData;
|
|
public ButtonDataBlock[] ButtonData;
|
|
|
|
public PayPriceReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.PayPriceReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 162;
|
|
Header.Reliable = true;
|
|
ObjectData = new ObjectDataBlock();
|
|
ButtonData = null;
|
|
}
|
|
|
|
public PayPriceReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ButtonData == null || ButtonData.Length != -1) {
|
|
ButtonData = new ButtonDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ButtonData[j] = new ButtonDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ButtonData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public PayPriceReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ButtonData == null || ButtonData.Length != count) {
|
|
ButtonData = new ButtonDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ButtonData[j] = new ButtonDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ButtonData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += ObjectData.Length;
|
|
length++;
|
|
for (int j = 0; j < ButtonData.Length; j++) { length += ButtonData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ButtonData.Length;
|
|
for (int j = 0; j < ButtonData.Length; j++) { ButtonData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += ObjectData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
ObjectData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ButtonDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ButtonDataCount = 0;
|
|
|
|
i = ButtonDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ButtonData.Length) {
|
|
int blockLength = ButtonData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ButtonDataStart) {
|
|
variableLength += blockLength;
|
|
++ButtonDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ButtonDataCount;
|
|
for (i = ButtonDataStart; i < ButtonDataStart + ButtonDataCount; i++) { ButtonData[i].ToBytes(packet, ref length); }
|
|
ButtonDataStart += ButtonDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ButtonDataStart < ButtonData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class KickUserPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class TargetBlockBlock : PacketBlock
|
|
{
|
|
public uint TargetIP;
|
|
public ushort TargetPort;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 6;
|
|
}
|
|
}
|
|
|
|
public TargetBlockBlock() { }
|
|
public TargetBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TargetIP = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TargetPort = (ushort)((bytes[i++] << 8) + bytes[i++]);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(TargetIP, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((TargetPort >> 8) % 256);
|
|
bytes[i++] = (byte)(TargetPort % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UserInfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public byte[] Reason;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 34;
|
|
if (Reason != null) { length += Reason.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public UserInfoBlock() { }
|
|
public UserInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Reason = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Reason, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)(Reason.Length % 256);
|
|
bytes[i++] = (byte)((Reason.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Reason, 0, bytes, i, Reason.Length); i += Reason.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += TargetBlock.Length;
|
|
length += UserInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TargetBlockBlock TargetBlock;
|
|
public UserInfoBlock UserInfo;
|
|
|
|
public KickUserPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.KickUser;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 163;
|
|
Header.Reliable = true;
|
|
TargetBlock = new TargetBlockBlock();
|
|
UserInfo = new UserInfoBlock();
|
|
}
|
|
|
|
public KickUserPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TargetBlock.FromBytes(bytes, ref i);
|
|
UserInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public KickUserPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TargetBlock.FromBytes(bytes, ref i);
|
|
UserInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TargetBlock.Length;
|
|
length += UserInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TargetBlock.ToBytes(bytes, ref i);
|
|
UserInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GodKickUserPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class UserInfoBlock : PacketBlock
|
|
{
|
|
public UUID GodID;
|
|
public UUID GodSessionID;
|
|
public UUID AgentID;
|
|
public uint KickFlags;
|
|
public byte[] Reason;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 54;
|
|
if (Reason != null) { length += Reason.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public UserInfoBlock() { }
|
|
public UserInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
GodID.FromBytes(bytes, i); i += 16;
|
|
GodSessionID.FromBytes(bytes, i); i += 16;
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
KickFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Reason = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Reason, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GodID.ToBytes(bytes, i); i += 16;
|
|
GodSessionID.ToBytes(bytes, i); i += 16;
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(KickFlags, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(Reason.Length % 256);
|
|
bytes[i++] = (byte)((Reason.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Reason, 0, bytes, i, Reason.Length); i += Reason.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += UserInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public UserInfoBlock UserInfo;
|
|
|
|
public GodKickUserPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GodKickUser;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 165;
|
|
Header.Reliable = true;
|
|
UserInfo = new UserInfoBlock();
|
|
}
|
|
|
|
public GodKickUserPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
UserInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GodKickUserPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
UserInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += UserInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
UserInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EjectUserPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID TargetID;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TargetID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TargetID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public EjectUserPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EjectUser;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 167;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public EjectUserPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EjectUserPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FreezeUserPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID TargetID;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TargetID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TargetID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public FreezeUserPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.FreezeUser;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 168;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public FreezeUserPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public FreezeUserPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarPropertiesRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID AvatarID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
AvatarID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
AvatarID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public AvatarPropertiesRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AvatarPropertiesRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 169;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public AvatarPropertiesRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AvatarPropertiesRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarPropertiesReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID AvatarID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
AvatarID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
AvatarID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PropertiesDataBlock : PacketBlock
|
|
{
|
|
public UUID ImageID;
|
|
public UUID FLImageID;
|
|
public UUID PartnerID;
|
|
public byte[] AboutText;
|
|
public byte[] FLAboutText;
|
|
public byte[] BornOn;
|
|
public byte[] ProfileURL;
|
|
public byte[] CharterMember;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 58;
|
|
if (AboutText != null) { length += AboutText.Length; }
|
|
if (FLAboutText != null) { length += FLAboutText.Length; }
|
|
if (BornOn != null) { length += BornOn.Length; }
|
|
if (ProfileURL != null) { length += ProfileURL.Length; }
|
|
if (CharterMember != null) { length += CharterMember.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public PropertiesDataBlock() { }
|
|
public PropertiesDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ImageID.FromBytes(bytes, i); i += 16;
|
|
FLImageID.FromBytes(bytes, i); i += 16;
|
|
PartnerID.FromBytes(bytes, i); i += 16;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
AboutText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, AboutText, 0, length); i += length;
|
|
length = bytes[i++];
|
|
FLAboutText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, FLAboutText, 0, length); i += length;
|
|
length = bytes[i++];
|
|
BornOn = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, BornOn, 0, length); i += length;
|
|
length = bytes[i++];
|
|
ProfileURL = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ProfileURL, 0, length); i += length;
|
|
length = bytes[i++];
|
|
CharterMember = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, CharterMember, 0, length); i += length;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ImageID.ToBytes(bytes, i); i += 16;
|
|
FLImageID.ToBytes(bytes, i); i += 16;
|
|
PartnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)(AboutText.Length % 256);
|
|
bytes[i++] = (byte)((AboutText.Length >> 8) % 256);
|
|
Buffer.BlockCopy(AboutText, 0, bytes, i, AboutText.Length); i += AboutText.Length;
|
|
bytes[i++] = (byte)FLAboutText.Length;
|
|
Buffer.BlockCopy(FLAboutText, 0, bytes, i, FLAboutText.Length); i += FLAboutText.Length;
|
|
bytes[i++] = (byte)BornOn.Length;
|
|
Buffer.BlockCopy(BornOn, 0, bytes, i, BornOn.Length); i += BornOn.Length;
|
|
bytes[i++] = (byte)ProfileURL.Length;
|
|
Buffer.BlockCopy(ProfileURL, 0, bytes, i, ProfileURL.Length); i += ProfileURL.Length;
|
|
bytes[i++] = (byte)CharterMember.Length;
|
|
Buffer.BlockCopy(CharterMember, 0, bytes, i, CharterMember.Length); i += CharterMember.Length;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += PropertiesData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public PropertiesDataBlock PropertiesData;
|
|
|
|
public AvatarPropertiesReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AvatarPropertiesReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 171;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
PropertiesData = new PropertiesDataBlock();
|
|
}
|
|
|
|
public AvatarPropertiesReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
PropertiesData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AvatarPropertiesReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
PropertiesData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += PropertiesData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
PropertiesData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarInterestsReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID AvatarID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
AvatarID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
AvatarID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PropertiesDataBlock : PacketBlock
|
|
{
|
|
public uint WantToMask;
|
|
public byte[] WantToText;
|
|
public uint SkillsMask;
|
|
public byte[] SkillsText;
|
|
public byte[] LanguagesText;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
if (WantToText != null) { length += WantToText.Length; }
|
|
if (SkillsText != null) { length += SkillsText.Length; }
|
|
if (LanguagesText != null) { length += LanguagesText.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public PropertiesDataBlock() { }
|
|
public PropertiesDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
WantToMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
WantToText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, WantToText, 0, length); i += length;
|
|
SkillsMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
SkillsText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SkillsText, 0, length); i += length;
|
|
length = bytes[i++];
|
|
LanguagesText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, LanguagesText, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(WantToMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)WantToText.Length;
|
|
Buffer.BlockCopy(WantToText, 0, bytes, i, WantToText.Length); i += WantToText.Length;
|
|
Utils.UIntToBytes(SkillsMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)SkillsText.Length;
|
|
Buffer.BlockCopy(SkillsText, 0, bytes, i, SkillsText.Length); i += SkillsText.Length;
|
|
bytes[i++] = (byte)LanguagesText.Length;
|
|
Buffer.BlockCopy(LanguagesText, 0, bytes, i, LanguagesText.Length); i += LanguagesText.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += PropertiesData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public PropertiesDataBlock PropertiesData;
|
|
|
|
public AvatarInterestsReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AvatarInterestsReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 172;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
PropertiesData = new PropertiesDataBlock();
|
|
}
|
|
|
|
public AvatarInterestsReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
PropertiesData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AvatarInterestsReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
PropertiesData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += PropertiesData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
PropertiesData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarGroupsReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID AvatarID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
AvatarID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
AvatarID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public ulong GroupPowers;
|
|
public bool AcceptNotices;
|
|
public byte[] GroupTitle;
|
|
public UUID GroupID;
|
|
public byte[] GroupName;
|
|
public UUID GroupInsigniaID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 43;
|
|
if (GroupTitle != null) { length += GroupTitle.Length; }
|
|
if (GroupName != null) { length += GroupName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
GroupPowers = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
AcceptNotices = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = bytes[i++];
|
|
GroupTitle = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, GroupTitle, 0, length); i += length;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
GroupName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, GroupName, 0, length); i += length;
|
|
GroupInsigniaID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(GroupPowers, bytes, i); i += 8;
|
|
bytes[i++] = (byte)((AcceptNotices) ? 1 : 0);
|
|
bytes[i++] = (byte)GroupTitle.Length;
|
|
Buffer.BlockCopy(GroupTitle, 0, bytes, i, GroupTitle.Length); i += GroupTitle.Length;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)GroupName.Length;
|
|
Buffer.BlockCopy(GroupName, 0, bytes, i, GroupName.Length); i += GroupName.Length;
|
|
GroupInsigniaID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class NewGroupDataBlock : PacketBlock
|
|
{
|
|
public bool ListInProfile;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public NewGroupDataBlock() { }
|
|
public NewGroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ListInProfile = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((ListInProfile) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < GroupData.Length; j++)
|
|
length += GroupData[j].Length;
|
|
length += NewGroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock[] GroupData;
|
|
public NewGroupDataBlock NewGroupData;
|
|
|
|
public AvatarGroupsReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AvatarGroupsReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 173;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = null;
|
|
NewGroupData = new NewGroupDataBlock();
|
|
}
|
|
|
|
public AvatarGroupsReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(GroupData == null || GroupData.Length != -1) {
|
|
GroupData = new GroupDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ GroupData[j] = new GroupDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ GroupData[j].FromBytes(bytes, ref i); }
|
|
NewGroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AvatarGroupsReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(GroupData == null || GroupData.Length != count) {
|
|
GroupData = new GroupDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ GroupData[j] = new GroupDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ GroupData[j].FromBytes(bytes, ref i); }
|
|
NewGroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += NewGroupData.Length;
|
|
length++;
|
|
for (int j = 0; j < GroupData.Length; j++) { length += GroupData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)GroupData.Length;
|
|
for (int j = 0; j < GroupData.Length; j++) { GroupData[j].ToBytes(bytes, ref i); }
|
|
NewGroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarPropertiesUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PropertiesDataBlock : PacketBlock
|
|
{
|
|
public UUID ImageID;
|
|
public UUID FLImageID;
|
|
public byte[] AboutText;
|
|
public byte[] FLAboutText;
|
|
public bool AllowPublish;
|
|
public bool MaturePublish;
|
|
public byte[] ProfileURL;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 38;
|
|
if (AboutText != null) { length += AboutText.Length; }
|
|
if (FLAboutText != null) { length += FLAboutText.Length; }
|
|
if (ProfileURL != null) { length += ProfileURL.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public PropertiesDataBlock() { }
|
|
public PropertiesDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ImageID.FromBytes(bytes, i); i += 16;
|
|
FLImageID.FromBytes(bytes, i); i += 16;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
AboutText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, AboutText, 0, length); i += length;
|
|
length = bytes[i++];
|
|
FLAboutText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, FLAboutText, 0, length); i += length;
|
|
AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = bytes[i++];
|
|
ProfileURL = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ProfileURL, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ImageID.ToBytes(bytes, i); i += 16;
|
|
FLImageID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)(AboutText.Length % 256);
|
|
bytes[i++] = (byte)((AboutText.Length >> 8) % 256);
|
|
Buffer.BlockCopy(AboutText, 0, bytes, i, AboutText.Length); i += AboutText.Length;
|
|
bytes[i++] = (byte)FLAboutText.Length;
|
|
Buffer.BlockCopy(FLAboutText, 0, bytes, i, FLAboutText.Length); i += FLAboutText.Length;
|
|
bytes[i++] = (byte)((AllowPublish) ? 1 : 0);
|
|
bytes[i++] = (byte)((MaturePublish) ? 1 : 0);
|
|
bytes[i++] = (byte)ProfileURL.Length;
|
|
Buffer.BlockCopy(ProfileURL, 0, bytes, i, ProfileURL.Length); i += ProfileURL.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += PropertiesData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public PropertiesDataBlock PropertiesData;
|
|
|
|
public AvatarPropertiesUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AvatarPropertiesUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 174;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
PropertiesData = new PropertiesDataBlock();
|
|
}
|
|
|
|
public AvatarPropertiesUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
PropertiesData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AvatarPropertiesUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
PropertiesData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += PropertiesData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
PropertiesData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarInterestsUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PropertiesDataBlock : PacketBlock
|
|
{
|
|
public uint WantToMask;
|
|
public byte[] WantToText;
|
|
public uint SkillsMask;
|
|
public byte[] SkillsText;
|
|
public byte[] LanguagesText;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
if (WantToText != null) { length += WantToText.Length; }
|
|
if (SkillsText != null) { length += SkillsText.Length; }
|
|
if (LanguagesText != null) { length += LanguagesText.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public PropertiesDataBlock() { }
|
|
public PropertiesDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
WantToMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
WantToText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, WantToText, 0, length); i += length;
|
|
SkillsMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
SkillsText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SkillsText, 0, length); i += length;
|
|
length = bytes[i++];
|
|
LanguagesText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, LanguagesText, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(WantToMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)WantToText.Length;
|
|
Buffer.BlockCopy(WantToText, 0, bytes, i, WantToText.Length); i += WantToText.Length;
|
|
Utils.UIntToBytes(SkillsMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)SkillsText.Length;
|
|
Buffer.BlockCopy(SkillsText, 0, bytes, i, SkillsText.Length); i += SkillsText.Length;
|
|
bytes[i++] = (byte)LanguagesText.Length;
|
|
Buffer.BlockCopy(LanguagesText, 0, bytes, i, LanguagesText.Length); i += LanguagesText.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += PropertiesData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public PropertiesDataBlock PropertiesData;
|
|
|
|
public AvatarInterestsUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AvatarInterestsUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 175;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
PropertiesData = new PropertiesDataBlock();
|
|
}
|
|
|
|
public AvatarInterestsUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
PropertiesData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AvatarInterestsUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
PropertiesData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += PropertiesData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
PropertiesData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarNotesReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID TargetID;
|
|
public byte[] Notes;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 18;
|
|
if (Notes != null) { length += Notes.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TargetID.FromBytes(bytes, i); i += 16;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Notes = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Notes, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TargetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)(Notes.Length % 256);
|
|
bytes[i++] = (byte)((Notes.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Notes, 0, bytes, i, Notes.Length); i += Notes.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public AvatarNotesReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AvatarNotesReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 176;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public AvatarNotesReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AvatarNotesReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarNotesUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID TargetID;
|
|
public byte[] Notes;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 18;
|
|
if (Notes != null) { length += Notes.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TargetID.FromBytes(bytes, i); i += 16;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Notes = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Notes, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TargetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)(Notes.Length % 256);
|
|
bytes[i++] = (byte)((Notes.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Notes, 0, bytes, i, Notes.Length); i += Notes.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public AvatarNotesUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AvatarNotesUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 177;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public AvatarNotesUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AvatarNotesUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarPicksReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID TargetID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
TargetID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
TargetID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID PickID;
|
|
public byte[] PickName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (PickName != null) { length += PickName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
PickID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
PickName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, PickName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
PickID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)PickName.Length;
|
|
Buffer.BlockCopy(PickName, 0, bytes, i, PickName.Length); i += PickName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock[] Data;
|
|
|
|
public AvatarPicksReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AvatarPicksReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 178;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = null;
|
|
}
|
|
|
|
public AvatarPicksReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AvatarPicksReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventInfoRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventDataBlock : PacketBlock
|
|
{
|
|
public uint EventID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public EventDataBlock() { }
|
|
public EventDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
EventID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(EventID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public EventDataBlock EventData;
|
|
|
|
public EventInfoRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EventInfoRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 179;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
EventData = new EventDataBlock();
|
|
}
|
|
|
|
public EventInfoRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EventInfoRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
EventData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventInfoReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventDataBlock : PacketBlock
|
|
{
|
|
public uint EventID;
|
|
public byte[] Creator;
|
|
public byte[] Name;
|
|
public byte[] Category;
|
|
public byte[] Desc;
|
|
public byte[] Date;
|
|
public uint DateUTC;
|
|
public uint Duration;
|
|
public uint Cover;
|
|
public uint Amount;
|
|
public byte[] SimName;
|
|
public Vector3d GlobalPos;
|
|
public uint EventFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 55;
|
|
if (Creator != null) { length += Creator.Length; }
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Category != null) { length += Category.Length; }
|
|
if (Desc != null) { length += Desc.Length; }
|
|
if (Date != null) { length += Date.Length; }
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public EventDataBlock() { }
|
|
public EventDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
EventID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Creator = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Creator, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Category = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Category, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Date = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Date, 0, length); i += length;
|
|
DateUTC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Duration = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Cover = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Amount = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
GlobalPos.FromBytes(bytes, i); i += 24;
|
|
EventFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(EventID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Creator.Length;
|
|
Buffer.BlockCopy(Creator, 0, bytes, i, Creator.Length); i += Creator.Length;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Category.Length;
|
|
Buffer.BlockCopy(Category, 0, bytes, i, Category.Length); i += Category.Length;
|
|
bytes[i++] = (byte)(Desc.Length % 256);
|
|
bytes[i++] = (byte)((Desc.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length;
|
|
bytes[i++] = (byte)Date.Length;
|
|
Buffer.BlockCopy(Date, 0, bytes, i, Date.Length); i += Date.Length;
|
|
Utils.UIntToBytes(DateUTC, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Duration, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Cover, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Amount, bytes, i); i += 4;
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
GlobalPos.ToBytes(bytes, i); i += 24;
|
|
Utils.UIntToBytes(EventFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public EventDataBlock EventData;
|
|
|
|
public EventInfoReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EventInfoReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 180;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
EventData = new EventDataBlock();
|
|
}
|
|
|
|
public EventInfoReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EventInfoReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
EventData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventNotificationAddRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventDataBlock : PacketBlock
|
|
{
|
|
public uint EventID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public EventDataBlock() { }
|
|
public EventDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
EventID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(EventID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public EventDataBlock EventData;
|
|
|
|
public EventNotificationAddRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EventNotificationAddRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 181;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
EventData = new EventDataBlock();
|
|
}
|
|
|
|
public EventNotificationAddRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EventNotificationAddRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
EventData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventNotificationRemoveRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventDataBlock : PacketBlock
|
|
{
|
|
public uint EventID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public EventDataBlock() { }
|
|
public EventDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
EventID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(EventID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public EventDataBlock EventData;
|
|
|
|
public EventNotificationRemoveRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EventNotificationRemoveRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 182;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
EventData = new EventDataBlock();
|
|
}
|
|
|
|
public EventNotificationRemoveRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EventNotificationRemoveRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
EventData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventGodDeletePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventDataBlock : PacketBlock
|
|
{
|
|
public uint EventID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public EventDataBlock() { }
|
|
public EventDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
EventID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(EventID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
public byte[] QueryText;
|
|
public uint QueryFlags;
|
|
public int QueryStart;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 25;
|
|
if (QueryText != null) { length += QueryText.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public QueryDataBlock() { }
|
|
public QueryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
QueryText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, QueryText, 0, length); i += length;
|
|
QueryFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
QueryStart = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)QueryText.Length;
|
|
Buffer.BlockCopy(QueryText, 0, bytes, i, QueryText.Length); i += QueryText.Length;
|
|
Utils.UIntToBytes(QueryFlags, bytes, i); i += 4;
|
|
Utils.IntToBytes(QueryStart, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
length += QueryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public EventDataBlock EventData;
|
|
public QueryDataBlock QueryData;
|
|
|
|
public EventGodDeletePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EventGodDelete;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 183;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
EventData = new EventDataBlock();
|
|
QueryData = new QueryDataBlock();
|
|
}
|
|
|
|
public EventGodDeletePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EventGodDeletePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
length += QueryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
EventData.ToBytes(bytes, ref i);
|
|
QueryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PickInfoReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID PickID;
|
|
public UUID CreatorID;
|
|
public bool TopPick;
|
|
public UUID ParcelID;
|
|
public byte[] Name;
|
|
public byte[] Desc;
|
|
public UUID SnapshotID;
|
|
public byte[] User;
|
|
public byte[] OriginalName;
|
|
public byte[] SimName;
|
|
public Vector3d PosGlobal;
|
|
public int SortOrder;
|
|
public bool Enabled;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 100;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Desc != null) { length += Desc.Length; }
|
|
if (User != null) { length += User.Length; }
|
|
if (OriginalName != null) { length += OriginalName.Length; }
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
PickID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
TopPick = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length;
|
|
SnapshotID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
User = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, User, 0, length); i += length;
|
|
length = bytes[i++];
|
|
OriginalName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, OriginalName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
PosGlobal.FromBytes(bytes, i); i += 24;
|
|
SortOrder = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Enabled = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
PickID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((TopPick) ? 1 : 0);
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)(Desc.Length % 256);
|
|
bytes[i++] = (byte)((Desc.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length;
|
|
SnapshotID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)User.Length;
|
|
Buffer.BlockCopy(User, 0, bytes, i, User.Length); i += User.Length;
|
|
bytes[i++] = (byte)OriginalName.Length;
|
|
Buffer.BlockCopy(OriginalName, 0, bytes, i, OriginalName.Length); i += OriginalName.Length;
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
PosGlobal.ToBytes(bytes, i); i += 24;
|
|
Utils.IntToBytes(SortOrder, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((Enabled) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public PickInfoReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.PickInfoReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 184;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public PickInfoReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public PickInfoReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PickInfoUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID PickID;
|
|
public UUID CreatorID;
|
|
public bool TopPick;
|
|
public UUID ParcelID;
|
|
public byte[] Name;
|
|
public byte[] Desc;
|
|
public UUID SnapshotID;
|
|
public Vector3d PosGlobal;
|
|
public int SortOrder;
|
|
public bool Enabled;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 97;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Desc != null) { length += Desc.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
PickID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
TopPick = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length;
|
|
SnapshotID.FromBytes(bytes, i); i += 16;
|
|
PosGlobal.FromBytes(bytes, i); i += 24;
|
|
SortOrder = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Enabled = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
PickID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((TopPick) ? 1 : 0);
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)(Desc.Length % 256);
|
|
bytes[i++] = (byte)((Desc.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length;
|
|
SnapshotID.ToBytes(bytes, i); i += 16;
|
|
PosGlobal.ToBytes(bytes, i); i += 24;
|
|
Utils.IntToBytes(SortOrder, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((Enabled) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public PickInfoUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.PickInfoUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 185;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public PickInfoUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public PickInfoUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PickDeletePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID PickID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
PickID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
PickID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public PickDeletePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.PickDelete;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 186;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public PickDeletePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public PickDeletePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PickGodDeletePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID PickID;
|
|
public UUID QueryID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
PickID.FromBytes(bytes, i); i += 16;
|
|
QueryID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
PickID.ToBytes(bytes, i); i += 16;
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public PickGodDeletePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.PickGodDelete;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 187;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public PickGodDeletePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public PickGodDeletePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptQuestionPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID TaskID;
|
|
public UUID ItemID;
|
|
public byte[] ObjectName;
|
|
public byte[] ObjectOwner;
|
|
public int Questions;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 38;
|
|
if (ObjectName != null) { length += ObjectName.Length; }
|
|
if (ObjectOwner != null) { length += ObjectOwner.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TaskID.FromBytes(bytes, i); i += 16;
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
ObjectName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ObjectName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
ObjectOwner = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ObjectOwner, 0, length); i += length;
|
|
Questions = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TaskID.ToBytes(bytes, i); i += 16;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)ObjectName.Length;
|
|
Buffer.BlockCopy(ObjectName, 0, bytes, i, ObjectName.Length); i += ObjectName.Length;
|
|
bytes[i++] = (byte)ObjectOwner.Length;
|
|
Buffer.BlockCopy(ObjectOwner, 0, bytes, i, ObjectOwner.Length); i += ObjectOwner.Length;
|
|
Utils.IntToBytes(Questions, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ExperienceBlock : PacketBlock
|
|
{
|
|
public UUID ExperienceID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ExperienceBlock() { }
|
|
public ExperienceBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ExperienceID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ExperienceID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
length += Experience.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock Data;
|
|
public ExperienceBlock Experience;
|
|
|
|
public ScriptQuestionPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ScriptQuestion;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 188;
|
|
Header.Reliable = true;
|
|
Data = new DataBlock();
|
|
Experience = new ExperienceBlock();
|
|
}
|
|
|
|
public ScriptQuestionPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Data.FromBytes(bytes, ref i);
|
|
Experience.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ScriptQuestionPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Data.FromBytes(bytes, ref i);
|
|
Experience.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
length += Experience.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
Experience.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptControlChangePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public bool TakeControls;
|
|
public uint Controls;
|
|
public bool PassToAgent;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 6;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TakeControls = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Controls = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PassToAgent = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((TakeControls) ? 1 : 0);
|
|
Utils.UIntToBytes(Controls, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((PassToAgent) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock[] Data;
|
|
|
|
public ScriptControlChangePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ScriptControlChange;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 189;
|
|
Header.Reliable = true;
|
|
Data = null;
|
|
}
|
|
|
|
public ScriptControlChangePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ScriptControlChangePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptDialogPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public byte[] FirstName;
|
|
public byte[] LastName;
|
|
public byte[] ObjectName;
|
|
public byte[] Message;
|
|
public int ChatChannel;
|
|
public UUID ImageID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 41;
|
|
if (FirstName != null) { length += FirstName.Length; }
|
|
if (LastName != null) { length += LastName.Length; }
|
|
if (ObjectName != null) { length += ObjectName.Length; }
|
|
if (Message != null) { length += Message.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
FirstName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, FirstName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
LastName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, LastName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
ObjectName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ObjectName, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
ChatChannel = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ImageID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)FirstName.Length;
|
|
Buffer.BlockCopy(FirstName, 0, bytes, i, FirstName.Length); i += FirstName.Length;
|
|
bytes[i++] = (byte)LastName.Length;
|
|
Buffer.BlockCopy(LastName, 0, bytes, i, LastName.Length); i += LastName.Length;
|
|
bytes[i++] = (byte)ObjectName.Length;
|
|
Buffer.BlockCopy(ObjectName, 0, bytes, i, ObjectName.Length); i += ObjectName.Length;
|
|
bytes[i++] = (byte)(Message.Length % 256);
|
|
bytes[i++] = (byte)((Message.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
Utils.IntToBytes(ChatChannel, bytes, i); i += 4;
|
|
ImageID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ButtonsBlock : PacketBlock
|
|
{
|
|
public byte[] ButtonLabel;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (ButtonLabel != null) { length += ButtonLabel.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ButtonsBlock() { }
|
|
public ButtonsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
ButtonLabel = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ButtonLabel, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)ButtonLabel.Length;
|
|
Buffer.BlockCopy(ButtonLabel, 0, bytes, i, ButtonLabel.Length); i += ButtonLabel.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class OwnerDataBlock : PacketBlock
|
|
{
|
|
public UUID OwnerID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public OwnerDataBlock() { }
|
|
public OwnerDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += Data.Length;
|
|
for (int j = 0; j < Buttons.Length; j++)
|
|
length += Buttons[j].Length;
|
|
for (int j = 0; j < OwnerData.Length; j++)
|
|
length += OwnerData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock Data;
|
|
public ButtonsBlock[] Buttons;
|
|
public OwnerDataBlock[] OwnerData;
|
|
|
|
public ScriptDialogPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ScriptDialog;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 190;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
Data = new DataBlock();
|
|
Buttons = null;
|
|
OwnerData = null;
|
|
}
|
|
|
|
public ScriptDialogPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Data.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Buttons == null || Buttons.Length != -1) {
|
|
Buttons = new ButtonsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Buttons[j] = new ButtonsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Buttons[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(OwnerData == null || OwnerData.Length != -1) {
|
|
OwnerData = new OwnerDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ OwnerData[j] = new OwnerDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ OwnerData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ScriptDialogPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Data.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Buttons == null || Buttons.Length != count) {
|
|
Buttons = new ButtonsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Buttons[j] = new ButtonsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Buttons[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(OwnerData == null || OwnerData.Length != count) {
|
|
OwnerData = new OwnerDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ OwnerData[j] = new OwnerDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ OwnerData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
length++;
|
|
for (int j = 0; j < Buttons.Length; j++) { length += Buttons[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < OwnerData.Length; j++) { length += OwnerData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Buttons.Length;
|
|
for (int j = 0; j < Buttons.Length; j++) { Buttons[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)OwnerData.Length;
|
|
for (int j = 0; j < OwnerData.Length; j++) { OwnerData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += Data.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
Data.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int ButtonsStart = 0;
|
|
int OwnerDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ButtonsCount = 0;
|
|
int OwnerDataCount = 0;
|
|
|
|
i = ButtonsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Buttons.Length) {
|
|
int blockLength = Buttons[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ButtonsStart) {
|
|
variableLength += blockLength;
|
|
++ButtonsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = OwnerDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < OwnerData.Length) {
|
|
int blockLength = OwnerData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == OwnerDataStart) {
|
|
variableLength += blockLength;
|
|
++OwnerDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ButtonsCount;
|
|
for (i = ButtonsStart; i < ButtonsStart + ButtonsCount; i++) { Buttons[i].ToBytes(packet, ref length); }
|
|
ButtonsStart += ButtonsCount;
|
|
|
|
packet[length++] = (byte)OwnerDataCount;
|
|
for (i = OwnerDataStart; i < OwnerDataStart + OwnerDataCount; i++) { OwnerData[i].ToBytes(packet, ref length); }
|
|
OwnerDataStart += OwnerDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ButtonsStart < Buttons.Length ||
|
|
OwnerDataStart < OwnerData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptDialogReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public int ChatChannel;
|
|
public int ButtonIndex;
|
|
public byte[] ButtonLabel;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 25;
|
|
if (ButtonLabel != null) { length += ButtonLabel.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
ChatChannel = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ButtonIndex = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
ButtonLabel = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ButtonLabel, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(ChatChannel, bytes, i); i += 4;
|
|
Utils.IntToBytes(ButtonIndex, bytes, i); i += 4;
|
|
bytes[i++] = (byte)ButtonLabel.Length;
|
|
Buffer.BlockCopy(ButtonLabel, 0, bytes, i, ButtonLabel.Length); i += ButtonLabel.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ScriptDialogReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ScriptDialogReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 191;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ScriptDialogReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ScriptDialogReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ForceScriptControlReleasePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public ForceScriptControlReleasePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ForceScriptControlRelease;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 192;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public ForceScriptControlReleasePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ForceScriptControlReleasePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RevokePermissionsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public uint ObjectPermissions;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
ObjectPermissions = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(ObjectPermissions, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public RevokePermissionsPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RevokePermissions;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 193;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public RevokePermissionsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RevokePermissionsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LoadURLPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public byte[] ObjectName;
|
|
public UUID ObjectID;
|
|
public UUID OwnerID;
|
|
public bool OwnerIsGroup;
|
|
public byte[] Message;
|
|
public byte[] URL;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 36;
|
|
if (ObjectName != null) { length += ObjectName.Length; }
|
|
if (Message != null) { length += Message.Length; }
|
|
if (URL != null) { length += URL.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
ObjectName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ObjectName, 0, length); i += length;
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
OwnerIsGroup = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = bytes[i++];
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
length = bytes[i++];
|
|
URL = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, URL, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)ObjectName.Length;
|
|
Buffer.BlockCopy(ObjectName, 0, bytes, i, ObjectName.Length); i += ObjectName.Length;
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((OwnerIsGroup) ? 1 : 0);
|
|
bytes[i++] = (byte)Message.Length;
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
bytes[i++] = (byte)URL.Length;
|
|
Buffer.BlockCopy(URL, 0, bytes, i, URL.Length); i += URL.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock Data;
|
|
|
|
public LoadURLPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.LoadURL;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 194;
|
|
Header.Reliable = true;
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public LoadURLPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public LoadURLPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptTeleportRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public byte[] ObjectName;
|
|
public byte[] SimName;
|
|
public Vector3 SimPosition;
|
|
public Vector3 LookAt;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 26;
|
|
if (ObjectName != null) { length += ObjectName.Length; }
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
ObjectName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ObjectName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
SimPosition.FromBytes(bytes, i); i += 12;
|
|
LookAt.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)ObjectName.Length;
|
|
Buffer.BlockCopy(ObjectName, 0, bytes, i, ObjectName.Length); i += ObjectName.Length;
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
SimPosition.ToBytes(bytes, i); i += 12;
|
|
LookAt.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock Data;
|
|
|
|
public ScriptTeleportRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ScriptTeleportRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 195;
|
|
Header.Reliable = true;
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ScriptTeleportRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ScriptTeleportRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelOverlayPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int SequenceID;
|
|
public byte[] Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 6;
|
|
if (Data != null) { length += Data.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
SequenceID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(SequenceID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(Data.Length % 256);
|
|
bytes[i++] = (byte)((Data.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelOverlayPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelOverlay;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 196;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelOverlayPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelOverlayPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelPropertiesRequestByIDPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int SequenceID;
|
|
public int LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
SequenceID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(SequenceID, bytes, i); i += 4;
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelPropertiesRequestByIDPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelPropertiesRequestByID;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 197;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelPropertiesRequestByIDPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelPropertiesRequestByIDPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelPropertiesUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
public uint Flags;
|
|
public uint ParcelFlags;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Desc;
|
|
public byte[] MusicURL;
|
|
public byte[] MediaURL;
|
|
public UUID MediaID;
|
|
public byte MediaAutoScale;
|
|
public UUID GroupID;
|
|
public int PassPrice;
|
|
public float PassHours;
|
|
public byte Category;
|
|
public UUID AuthBuyerID;
|
|
public UUID SnapshotID;
|
|
public Vector3 UserLocation;
|
|
public Vector3 UserLookAt;
|
|
public byte LandingType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 119;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Desc != null) { length += Desc.Length; }
|
|
if (MusicURL != null) { length += MusicURL.Length; }
|
|
if (MediaURL != null) { length += MediaURL.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ParcelFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length;
|
|
length = bytes[i++];
|
|
MusicURL = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MusicURL, 0, length); i += length;
|
|
length = bytes[i++];
|
|
MediaURL = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MediaURL, 0, length); i += length;
|
|
MediaID.FromBytes(bytes, i); i += 16;
|
|
MediaAutoScale = (byte)bytes[i++];
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
PassPrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PassHours = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Category = (byte)bytes[i++];
|
|
AuthBuyerID.FromBytes(bytes, i); i += 16;
|
|
SnapshotID.FromBytes(bytes, i); i += 16;
|
|
UserLocation.FromBytes(bytes, i); i += 12;
|
|
UserLookAt.FromBytes(bytes, i); i += 12;
|
|
LandingType = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ParcelFlags, bytes, i); i += 4;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Desc.Length;
|
|
Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length;
|
|
bytes[i++] = (byte)MusicURL.Length;
|
|
Buffer.BlockCopy(MusicURL, 0, bytes, i, MusicURL.Length); i += MusicURL.Length;
|
|
bytes[i++] = (byte)MediaURL.Length;
|
|
Buffer.BlockCopy(MediaURL, 0, bytes, i, MediaURL.Length); i += MediaURL.Length;
|
|
MediaID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = MediaAutoScale;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(PassPrice, bytes, i); i += 4;
|
|
Utils.FloatToBytes(PassHours, bytes, i); i += 4;
|
|
bytes[i++] = Category;
|
|
AuthBuyerID.ToBytes(bytes, i); i += 16;
|
|
SnapshotID.ToBytes(bytes, i); i += 16;
|
|
UserLocation.ToBytes(bytes, i); i += 12;
|
|
UserLookAt.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = LandingType;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelPropertiesUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelPropertiesUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 198;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelPropertiesUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelPropertiesUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelReturnObjectsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
public uint ReturnType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ReturnType = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ReturnType, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TaskIDsBlock : PacketBlock
|
|
{
|
|
public UUID TaskID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TaskIDsBlock() { }
|
|
public TaskIDsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TaskID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TaskID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class OwnerIDsBlock : PacketBlock
|
|
{
|
|
public UUID OwnerID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public OwnerIDsBlock() { }
|
|
public OwnerIDsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
for (int j = 0; j < TaskIDs.Length; j++)
|
|
length += TaskIDs[j].Length;
|
|
for (int j = 0; j < OwnerIDs.Length; j++)
|
|
length += OwnerIDs[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
public TaskIDsBlock[] TaskIDs;
|
|
public OwnerIDsBlock[] OwnerIDs;
|
|
|
|
public ParcelReturnObjectsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ParcelReturnObjects;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 199;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
TaskIDs = null;
|
|
OwnerIDs = null;
|
|
}
|
|
|
|
public ParcelReturnObjectsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(TaskIDs == null || TaskIDs.Length != -1) {
|
|
TaskIDs = new TaskIDsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ TaskIDs[j] = new TaskIDsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ TaskIDs[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(OwnerIDs == null || OwnerIDs.Length != -1) {
|
|
OwnerIDs = new OwnerIDsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ OwnerIDs[j] = new OwnerIDsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ OwnerIDs[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ParcelReturnObjectsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(TaskIDs == null || TaskIDs.Length != count) {
|
|
TaskIDs = new TaskIDsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ TaskIDs[j] = new TaskIDsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ TaskIDs[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(OwnerIDs == null || OwnerIDs.Length != count) {
|
|
OwnerIDs = new OwnerIDsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ OwnerIDs[j] = new OwnerIDsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ OwnerIDs[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
length++;
|
|
for (int j = 0; j < TaskIDs.Length; j++) { length += TaskIDs[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < OwnerIDs.Length; j++) { length += OwnerIDs[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)TaskIDs.Length;
|
|
for (int j = 0; j < TaskIDs.Length; j++) { TaskIDs[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)OwnerIDs.Length;
|
|
for (int j = 0; j < OwnerIDs.Length; j++) { OwnerIDs[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += ParcelData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
ParcelData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int TaskIDsStart = 0;
|
|
int OwnerIDsStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int TaskIDsCount = 0;
|
|
int OwnerIDsCount = 0;
|
|
|
|
i = TaskIDsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < TaskIDs.Length) {
|
|
int blockLength = TaskIDs[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == TaskIDsStart) {
|
|
variableLength += blockLength;
|
|
++TaskIDsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = OwnerIDsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < OwnerIDs.Length) {
|
|
int blockLength = OwnerIDs[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == OwnerIDsStart) {
|
|
variableLength += blockLength;
|
|
++OwnerIDsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)TaskIDsCount;
|
|
for (i = TaskIDsStart; i < TaskIDsStart + TaskIDsCount; i++) { TaskIDs[i].ToBytes(packet, ref length); }
|
|
TaskIDsStart += TaskIDsCount;
|
|
|
|
packet[length++] = (byte)OwnerIDsCount;
|
|
for (i = OwnerIDsStart; i < OwnerIDsStart + OwnerIDsCount; i++) { OwnerIDs[i].ToBytes(packet, ref length); }
|
|
OwnerIDsStart += OwnerIDsCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
TaskIDsStart < TaskIDs.Length ||
|
|
OwnerIDsStart < OwnerIDs.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelSetOtherCleanTimePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
public int OtherCleanTime;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OtherCleanTime = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
Utils.IntToBytes(OtherCleanTime, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelSetOtherCleanTimePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelSetOtherCleanTime;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 200;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelSetOtherCleanTimePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelSetOtherCleanTimePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDisableObjectsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
public uint ReturnType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ReturnType = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ReturnType, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TaskIDsBlock : PacketBlock
|
|
{
|
|
public UUID TaskID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TaskIDsBlock() { }
|
|
public TaskIDsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TaskID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TaskID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class OwnerIDsBlock : PacketBlock
|
|
{
|
|
public UUID OwnerID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public OwnerIDsBlock() { }
|
|
public OwnerIDsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
for (int j = 0; j < TaskIDs.Length; j++)
|
|
length += TaskIDs[j].Length;
|
|
for (int j = 0; j < OwnerIDs.Length; j++)
|
|
length += OwnerIDs[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
public TaskIDsBlock[] TaskIDs;
|
|
public OwnerIDsBlock[] OwnerIDs;
|
|
|
|
public ParcelDisableObjectsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ParcelDisableObjects;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 201;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
TaskIDs = null;
|
|
OwnerIDs = null;
|
|
}
|
|
|
|
public ParcelDisableObjectsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(TaskIDs == null || TaskIDs.Length != -1) {
|
|
TaskIDs = new TaskIDsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ TaskIDs[j] = new TaskIDsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ TaskIDs[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(OwnerIDs == null || OwnerIDs.Length != -1) {
|
|
OwnerIDs = new OwnerIDsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ OwnerIDs[j] = new OwnerIDsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ OwnerIDs[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ParcelDisableObjectsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(TaskIDs == null || TaskIDs.Length != count) {
|
|
TaskIDs = new TaskIDsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ TaskIDs[j] = new TaskIDsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ TaskIDs[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(OwnerIDs == null || OwnerIDs.Length != count) {
|
|
OwnerIDs = new OwnerIDsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ OwnerIDs[j] = new OwnerIDsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ OwnerIDs[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
length++;
|
|
for (int j = 0; j < TaskIDs.Length; j++) { length += TaskIDs[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < OwnerIDs.Length; j++) { length += OwnerIDs[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)TaskIDs.Length;
|
|
for (int j = 0; j < TaskIDs.Length; j++) { TaskIDs[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)OwnerIDs.Length;
|
|
for (int j = 0; j < OwnerIDs.Length; j++) { OwnerIDs[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += ParcelData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
ParcelData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int TaskIDsStart = 0;
|
|
int OwnerIDsStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int TaskIDsCount = 0;
|
|
int OwnerIDsCount = 0;
|
|
|
|
i = TaskIDsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < TaskIDs.Length) {
|
|
int blockLength = TaskIDs[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == TaskIDsStart) {
|
|
variableLength += blockLength;
|
|
++TaskIDsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = OwnerIDsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < OwnerIDs.Length) {
|
|
int blockLength = OwnerIDs[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == OwnerIDsStart) {
|
|
variableLength += blockLength;
|
|
++OwnerIDsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)TaskIDsCount;
|
|
for (i = TaskIDsStart; i < TaskIDsStart + TaskIDsCount; i++) { TaskIDs[i].ToBytes(packet, ref length); }
|
|
TaskIDsStart += TaskIDsCount;
|
|
|
|
packet[length++] = (byte)OwnerIDsCount;
|
|
for (i = OwnerIDsStart; i < OwnerIDsStart + OwnerIDsCount; i++) { OwnerIDs[i].ToBytes(packet, ref length); }
|
|
OwnerIDsStart += OwnerIDsCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
TaskIDsStart < TaskIDs.Length ||
|
|
OwnerIDsStart < OwnerIDs.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelSelectObjectsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
public uint ReturnType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ReturnType = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ReturnType, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ReturnIDsBlock : PacketBlock
|
|
{
|
|
public UUID ReturnID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ReturnIDsBlock() { }
|
|
public ReturnIDsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ReturnID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ReturnID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
for (int j = 0; j < ReturnIDs.Length; j++)
|
|
length += ReturnIDs[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
public ReturnIDsBlock[] ReturnIDs;
|
|
|
|
public ParcelSelectObjectsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ParcelSelectObjects;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 202;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
ReturnIDs = null;
|
|
}
|
|
|
|
public ParcelSelectObjectsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ReturnIDs == null || ReturnIDs.Length != -1) {
|
|
ReturnIDs = new ReturnIDsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ReturnIDs[j] = new ReturnIDsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ReturnIDs[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ParcelSelectObjectsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ReturnIDs == null || ReturnIDs.Length != count) {
|
|
ReturnIDs = new ReturnIDsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ReturnIDs[j] = new ReturnIDsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ReturnIDs[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
length++;
|
|
for (int j = 0; j < ReturnIDs.Length; j++) { length += ReturnIDs[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ReturnIDs.Length;
|
|
for (int j = 0; j < ReturnIDs.Length; j++) { ReturnIDs[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += ParcelData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
ParcelData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ReturnIDsStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ReturnIDsCount = 0;
|
|
|
|
i = ReturnIDsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ReturnIDs.Length) {
|
|
int blockLength = ReturnIDs[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ReturnIDsStart) {
|
|
variableLength += blockLength;
|
|
++ReturnIDsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ReturnIDsCount;
|
|
for (i = ReturnIDsStart; i < ReturnIDsStart + ReturnIDsCount; i++) { ReturnIDs[i].ToBytes(packet, ref length); }
|
|
ReturnIDsStart += ReturnIDsCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ReturnIDsStart < ReturnIDs.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EstateCovenantRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public EstateCovenantRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EstateCovenantRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 203;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public EstateCovenantRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EstateCovenantRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EstateCovenantReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID CovenantID;
|
|
public uint CovenantTimestamp;
|
|
public byte[] EstateName;
|
|
public UUID EstateOwnerID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 37;
|
|
if (EstateName != null) { length += EstateName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
CovenantID.FromBytes(bytes, i); i += 16;
|
|
CovenantTimestamp = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
EstateName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, EstateName, 0, length); i += length;
|
|
EstateOwnerID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
CovenantID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(CovenantTimestamp, bytes, i); i += 4;
|
|
bytes[i++] = (byte)EstateName.Length;
|
|
Buffer.BlockCopy(EstateName, 0, bytes, i, EstateName.Length); i += EstateName.Length;
|
|
EstateOwnerID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock Data;
|
|
|
|
public EstateCovenantReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EstateCovenantReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 204;
|
|
Header.Reliable = true;
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public EstateCovenantReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EstateCovenantReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ForceObjectSelectPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class HeaderBlock : PacketBlock
|
|
{
|
|
public bool ResetList;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public HeaderBlock() { }
|
|
public HeaderBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ResetList = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((ResetList) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += _Header.Length;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public HeaderBlock _Header;
|
|
public DataBlock[] Data;
|
|
|
|
public ForceObjectSelectPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ForceObjectSelect;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 205;
|
|
Header.Reliable = true;
|
|
_Header = new HeaderBlock();
|
|
Data = null;
|
|
}
|
|
|
|
public ForceObjectSelectPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
_Header.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ForceObjectSelectPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
_Header.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += _Header.Length;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
_Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += _Header.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
_Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelBuyPassPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelBuyPassPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelBuyPass;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 206;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelBuyPassPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelBuyPassPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDeedToGroupPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public int LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ParcelDeedToGroupPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelDeedToGroup;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 207;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ParcelDeedToGroupPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelDeedToGroupPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelReclaimPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ParcelReclaimPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelReclaim;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 208;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ParcelReclaimPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelReclaimPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelClaimPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public bool IsGroupOwned;
|
|
public bool Final;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 18;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
IsGroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Final = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsGroupOwned) ? 1 : 0);
|
|
bytes[i++] = (byte)((Final) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public float West;
|
|
public float South;
|
|
public float East;
|
|
public float North;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
West = Utils.BytesToFloat(bytes, i); i += 4;
|
|
South = Utils.BytesToFloat(bytes, i); i += 4;
|
|
East = Utils.BytesToFloat(bytes, i); i += 4;
|
|
North = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.FloatToBytes(West, bytes, i); i += 4;
|
|
Utils.FloatToBytes(South, bytes, i); i += 4;
|
|
Utils.FloatToBytes(East, bytes, i); i += 4;
|
|
Utils.FloatToBytes(North, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
for (int j = 0; j < ParcelData.Length; j++)
|
|
length += ParcelData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
public ParcelDataBlock[] ParcelData;
|
|
|
|
public ParcelClaimPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ParcelClaim;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 209;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
ParcelData = null;
|
|
}
|
|
|
|
public ParcelClaimPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParcelData == null || ParcelData.Length != -1) {
|
|
ParcelData = new ParcelDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParcelData[j] = new ParcelDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParcelData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ParcelClaimPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParcelData == null || ParcelData.Length != count) {
|
|
ParcelData = new ParcelDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParcelData[j] = new ParcelDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParcelData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
length++;
|
|
for (int j = 0; j < ParcelData.Length; j++) { length += ParcelData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ParcelData.Length;
|
|
for (int j = 0; j < ParcelData.Length; j++) { ParcelData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += Data.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
Data.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ParcelDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ParcelDataCount = 0;
|
|
|
|
i = ParcelDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ParcelData.Length) {
|
|
int blockLength = ParcelData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ParcelDataStart) {
|
|
variableLength += blockLength;
|
|
++ParcelDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ParcelDataCount;
|
|
for (i = ParcelDataStart; i < ParcelDataStart + ParcelDataCount; i++) { ParcelData[i].ToBytes(packet, ref length); }
|
|
ParcelDataStart += ParcelDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ParcelDataStart < ParcelData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelJoinPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public float West;
|
|
public float South;
|
|
public float East;
|
|
public float North;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
West = Utils.BytesToFloat(bytes, i); i += 4;
|
|
South = Utils.BytesToFloat(bytes, i); i += 4;
|
|
East = Utils.BytesToFloat(bytes, i); i += 4;
|
|
North = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.FloatToBytes(West, bytes, i); i += 4;
|
|
Utils.FloatToBytes(South, bytes, i); i += 4;
|
|
Utils.FloatToBytes(East, bytes, i); i += 4;
|
|
Utils.FloatToBytes(North, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelJoinPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelJoin;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 210;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelJoinPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelJoinPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDividePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public float West;
|
|
public float South;
|
|
public float East;
|
|
public float North;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
West = Utils.BytesToFloat(bytes, i); i += 4;
|
|
South = Utils.BytesToFloat(bytes, i); i += 4;
|
|
East = Utils.BytesToFloat(bytes, i); i += 4;
|
|
North = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.FloatToBytes(West, bytes, i); i += 4;
|
|
Utils.FloatToBytes(South, bytes, i); i += 4;
|
|
Utils.FloatToBytes(East, bytes, i); i += 4;
|
|
Utils.FloatToBytes(North, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelDividePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelDivide;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 211;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelDividePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelDividePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelReleasePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ParcelReleasePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelRelease;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 212;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ParcelReleasePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelReleasePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelBuyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public bool IsGroupOwned;
|
|
public bool RemoveContribution;
|
|
public int LocalID;
|
|
public bool Final;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 23;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
IsGroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
RemoveContribution = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Final = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsGroupOwned) ? 1 : 0);
|
|
bytes[i++] = (byte)((RemoveContribution) ? 1 : 0);
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((Final) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int Price;
|
|
public int Area;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Price = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Area = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(Price, bytes, i); i += 4;
|
|
Utils.IntToBytes(Area, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelBuyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelBuy;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 213;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelBuyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelBuyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelGodForceOwnerPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID OwnerID;
|
|
public int LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ParcelGodForceOwnerPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelGodForceOwner;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 214;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ParcelGodForceOwnerPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelGodForceOwnerPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelAccessListRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public int SequenceID;
|
|
public uint Flags;
|
|
public int LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
SequenceID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(SequenceID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ParcelAccessListRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelAccessListRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 215;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ParcelAccessListRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelAccessListRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelAccessListReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public int SequenceID;
|
|
public uint Flags;
|
|
public int LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 28;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SequenceID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(SequenceID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ListBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public int Time;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 24;
|
|
}
|
|
}
|
|
|
|
public ListBlock() { }
|
|
public ListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
Time = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(Time, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += Data.Length;
|
|
for (int j = 0; j < List.Length; j++)
|
|
length += List[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock Data;
|
|
public ListBlock[] List;
|
|
|
|
public ParcelAccessListReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ParcelAccessListReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 216;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
Data = new DataBlock();
|
|
List = null;
|
|
}
|
|
|
|
public ParcelAccessListReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Data.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(List == null || List.Length != -1) {
|
|
List = new ListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ List[j] = new ListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ List[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ParcelAccessListReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Data.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(List == null || List.Length != count) {
|
|
List = new ListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ List[j] = new ListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ List[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
length++;
|
|
for (int j = 0; j < List.Length; j++) { length += List[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)List.Length;
|
|
for (int j = 0; j < List.Length; j++) { List[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += Data.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
Data.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ListCount = 0;
|
|
|
|
i = ListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < List.Length) {
|
|
int blockLength = List[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ListStart) {
|
|
variableLength += blockLength;
|
|
++ListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ListCount;
|
|
for (i = ListStart; i < ListStart + ListCount; i++) { List[i].ToBytes(packet, ref length); }
|
|
ListStart += ListCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ListStart < List.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelAccessListUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public uint Flags;
|
|
public int LocalID;
|
|
public UUID TransactionID;
|
|
public int SequenceID;
|
|
public int Sections;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
SequenceID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Sections = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(SequenceID, bytes, i); i += 4;
|
|
Utils.IntToBytes(Sections, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ListBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public int Time;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 24;
|
|
}
|
|
}
|
|
|
|
public ListBlock() { }
|
|
public ListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
Time = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(Time, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
for (int j = 0; j < List.Length; j++)
|
|
length += List[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
public ListBlock[] List;
|
|
|
|
public ParcelAccessListUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ParcelAccessListUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 217;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
List = null;
|
|
}
|
|
|
|
public ParcelAccessListUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(List == null || List.Length != -1) {
|
|
List = new ListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ List[j] = new ListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ List[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ParcelAccessListUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(List == null || List.Length != count) {
|
|
List = new ListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ List[j] = new ListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ List[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
length++;
|
|
for (int j = 0; j < List.Length; j++) { length += List[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)List.Length;
|
|
for (int j = 0; j < List.Length; j++) { List[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += Data.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
Data.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ListCount = 0;
|
|
|
|
i = ListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < List.Length) {
|
|
int blockLength = List[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ListStart) {
|
|
variableLength += blockLength;
|
|
++ListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ListCount;
|
|
for (i = ListStart; i < ListStart + ListCount; i++) { List[i].ToBytes(packet, ref length); }
|
|
ListStart += ListCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ListStart < List.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDwellRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
public UUID ParcelID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ParcelDwellRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelDwellRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 218;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ParcelDwellRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelDwellRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDwellReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
public UUID ParcelID;
|
|
public float Dwell;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 24;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ParcelID.FromBytes(bytes, i); i += 16;
|
|
Dwell = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
ParcelID.ToBytes(bytes, i); i += 16;
|
|
Utils.FloatToBytes(Dwell, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ParcelDwellReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelDwellReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 219;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ParcelDwellReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelDwellReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelGodMarkAsContentPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelGodMarkAsContentPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelGodMarkAsContent;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 227;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelGodMarkAsContentPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelGodMarkAsContentPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ViewerStartAuctionPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
public UUID SnapshotID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SnapshotID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
SnapshotID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ViewerStartAuctionPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ViewerStartAuction;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 228;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ViewerStartAuctionPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ViewerStartAuctionPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UUIDNameRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class UUIDNameBlockBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public UUIDNameBlockBlock() { }
|
|
public UUIDNameBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++)
|
|
length += UUIDNameBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public UUIDNameBlockBlock[] UUIDNameBlock;
|
|
|
|
public UUIDNameRequestPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.UUIDNameRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 235;
|
|
Header.Reliable = true;
|
|
UUIDNameBlock = null;
|
|
}
|
|
|
|
public UUIDNameRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(UUIDNameBlock == null || UUIDNameBlock.Length != -1) {
|
|
UUIDNameBlock = new UUIDNameBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j] = new UUIDNameBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public UUIDNameRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(UUIDNameBlock == null || UUIDNameBlock.Length != count) {
|
|
UUIDNameBlock = new UUIDNameBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j] = new UUIDNameBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++) { length += UUIDNameBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)UUIDNameBlock.Length;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++) { UUIDNameBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int UUIDNameBlockStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int UUIDNameBlockCount = 0;
|
|
|
|
i = UUIDNameBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < UUIDNameBlock.Length) {
|
|
int blockLength = UUIDNameBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == UUIDNameBlockStart) {
|
|
variableLength += blockLength;
|
|
++UUIDNameBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)UUIDNameBlockCount;
|
|
for (i = UUIDNameBlockStart; i < UUIDNameBlockStart + UUIDNameBlockCount; i++) { UUIDNameBlock[i].ToBytes(packet, ref length); }
|
|
UUIDNameBlockStart += UUIDNameBlockCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
UUIDNameBlockStart < UUIDNameBlock.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UUIDNameReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class UUIDNameBlockBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public byte[] FirstName;
|
|
public byte[] LastName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 18;
|
|
if (FirstName != null) { length += FirstName.Length; }
|
|
if (LastName != null) { length += LastName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public UUIDNameBlockBlock() { }
|
|
public UUIDNameBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
FirstName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, FirstName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
LastName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, LastName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)FirstName.Length;
|
|
Buffer.BlockCopy(FirstName, 0, bytes, i, FirstName.Length); i += FirstName.Length;
|
|
bytes[i++] = (byte)LastName.Length;
|
|
Buffer.BlockCopy(LastName, 0, bytes, i, LastName.Length); i += LastName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++)
|
|
length += UUIDNameBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public UUIDNameBlockBlock[] UUIDNameBlock;
|
|
|
|
public UUIDNameReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.UUIDNameReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 236;
|
|
Header.Reliable = true;
|
|
UUIDNameBlock = null;
|
|
}
|
|
|
|
public UUIDNameReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(UUIDNameBlock == null || UUIDNameBlock.Length != -1) {
|
|
UUIDNameBlock = new UUIDNameBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j] = new UUIDNameBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public UUIDNameReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(UUIDNameBlock == null || UUIDNameBlock.Length != count) {
|
|
UUIDNameBlock = new UUIDNameBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j] = new UUIDNameBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++) { length += UUIDNameBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)UUIDNameBlock.Length;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++) { UUIDNameBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int UUIDNameBlockStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int UUIDNameBlockCount = 0;
|
|
|
|
i = UUIDNameBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < UUIDNameBlock.Length) {
|
|
int blockLength = UUIDNameBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == UUIDNameBlockStart) {
|
|
variableLength += blockLength;
|
|
++UUIDNameBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)UUIDNameBlockCount;
|
|
for (i = UUIDNameBlockStart; i < UUIDNameBlockStart + UUIDNameBlockCount; i++) { UUIDNameBlock[i].ToBytes(packet, ref length); }
|
|
UUIDNameBlockStart += UUIDNameBlockCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
UUIDNameBlockStart < UUIDNameBlock.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UUIDGroupNameRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class UUIDNameBlockBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public UUIDNameBlockBlock() { }
|
|
public UUIDNameBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++)
|
|
length += UUIDNameBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public UUIDNameBlockBlock[] UUIDNameBlock;
|
|
|
|
public UUIDGroupNameRequestPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.UUIDGroupNameRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 237;
|
|
Header.Reliable = true;
|
|
UUIDNameBlock = null;
|
|
}
|
|
|
|
public UUIDGroupNameRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(UUIDNameBlock == null || UUIDNameBlock.Length != -1) {
|
|
UUIDNameBlock = new UUIDNameBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j] = new UUIDNameBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public UUIDGroupNameRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(UUIDNameBlock == null || UUIDNameBlock.Length != count) {
|
|
UUIDNameBlock = new UUIDNameBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j] = new UUIDNameBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++) { length += UUIDNameBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)UUIDNameBlock.Length;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++) { UUIDNameBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int UUIDNameBlockStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int UUIDNameBlockCount = 0;
|
|
|
|
i = UUIDNameBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < UUIDNameBlock.Length) {
|
|
int blockLength = UUIDNameBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == UUIDNameBlockStart) {
|
|
variableLength += blockLength;
|
|
++UUIDNameBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)UUIDNameBlockCount;
|
|
for (i = UUIDNameBlockStart; i < UUIDNameBlockStart + UUIDNameBlockCount; i++) { UUIDNameBlock[i].ToBytes(packet, ref length); }
|
|
UUIDNameBlockStart += UUIDNameBlockCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
UUIDNameBlockStart < UUIDNameBlock.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UUIDGroupNameReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class UUIDNameBlockBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public byte[] GroupName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (GroupName != null) { length += GroupName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public UUIDNameBlockBlock() { }
|
|
public UUIDNameBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
GroupName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, GroupName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)GroupName.Length;
|
|
Buffer.BlockCopy(GroupName, 0, bytes, i, GroupName.Length); i += GroupName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++)
|
|
length += UUIDNameBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public UUIDNameBlockBlock[] UUIDNameBlock;
|
|
|
|
public UUIDGroupNameReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.UUIDGroupNameReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 238;
|
|
Header.Reliable = true;
|
|
UUIDNameBlock = null;
|
|
}
|
|
|
|
public UUIDGroupNameReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(UUIDNameBlock == null || UUIDNameBlock.Length != -1) {
|
|
UUIDNameBlock = new UUIDNameBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j] = new UUIDNameBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public UUIDGroupNameReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(UUIDNameBlock == null || UUIDNameBlock.Length != count) {
|
|
UUIDNameBlock = new UUIDNameBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j] = new UUIDNameBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ UUIDNameBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++) { length += UUIDNameBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)UUIDNameBlock.Length;
|
|
for (int j = 0; j < UUIDNameBlock.Length; j++) { UUIDNameBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int UUIDNameBlockStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int UUIDNameBlockCount = 0;
|
|
|
|
i = UUIDNameBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < UUIDNameBlock.Length) {
|
|
int blockLength = UUIDNameBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == UUIDNameBlockStart) {
|
|
variableLength += blockLength;
|
|
++UUIDNameBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)UUIDNameBlockCount;
|
|
for (i = UUIDNameBlockStart; i < UUIDNameBlockStart + UUIDNameBlockCount; i++) { UUIDNameBlock[i].ToBytes(packet, ref length); }
|
|
UUIDNameBlockStart += UUIDNameBlockCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
UUIDNameBlockStart < UUIDNameBlock.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChildAgentDyingPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public ChildAgentDyingPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ChildAgentDying;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 240;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public ChildAgentDyingPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ChildAgentDyingPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChildAgentUnknownPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public ChildAgentUnknownPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ChildAgentUnknown;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 241;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public ChildAgentUnknownPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ChildAgentUnknownPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GetScriptRunningPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ScriptBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public ScriptBlock() { }
|
|
public ScriptBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Script.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ScriptBlock Script;
|
|
|
|
public GetScriptRunningPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GetScriptRunning;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 243;
|
|
Header.Reliable = true;
|
|
Script = new ScriptBlock();
|
|
}
|
|
|
|
public GetScriptRunningPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Script.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GetScriptRunningPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Script.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Script.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Script.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptRunningReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ScriptBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public UUID ItemID;
|
|
public bool Running;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public ScriptBlock() { }
|
|
public ScriptBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
Running = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Running) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Script.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ScriptBlock Script;
|
|
|
|
public ScriptRunningReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ScriptRunningReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 244;
|
|
Header.Reliable = true;
|
|
Script = new ScriptBlock();
|
|
}
|
|
|
|
public ScriptRunningReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Script.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ScriptRunningReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Script.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Script.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Script.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SetScriptRunningPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public UUID ItemID;
|
|
public bool Running;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public ScriptBlock() { }
|
|
public ScriptBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
Running = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Running) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Script.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ScriptBlock Script;
|
|
|
|
public SetScriptRunningPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SetScriptRunning;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 245;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Script = new ScriptBlock();
|
|
}
|
|
|
|
public SetScriptRunningPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Script.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SetScriptRunningPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Script.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Script.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Script.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptResetPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public ScriptBlock() { }
|
|
public ScriptBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Script.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ScriptBlock Script;
|
|
|
|
public ScriptResetPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ScriptReset;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 246;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Script = new ScriptBlock();
|
|
}
|
|
|
|
public ScriptResetPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Script.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ScriptResetPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Script.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Script.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Script.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptSensorRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class RequesterBlock : PacketBlock
|
|
{
|
|
public UUID SourceID;
|
|
public UUID RequestID;
|
|
public UUID SearchID;
|
|
public Vector3 SearchPos;
|
|
public Quaternion SearchDir;
|
|
public byte[] SearchName;
|
|
public int Type;
|
|
public float Range;
|
|
public float Arc;
|
|
public ulong RegionHandle;
|
|
public byte SearchRegions;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 94;
|
|
if (SearchName != null) { length += SearchName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RequesterBlock() { }
|
|
public RequesterBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
SourceID.FromBytes(bytes, i); i += 16;
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
SearchID.FromBytes(bytes, i); i += 16;
|
|
SearchPos.FromBytes(bytes, i); i += 12;
|
|
SearchDir.FromBytes(bytes, i, true); i += 12;
|
|
length = bytes[i++];
|
|
SearchName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SearchName, 0, length); i += length;
|
|
Type = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Range = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Arc = Utils.BytesToFloat(bytes, i); i += 4;
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
SearchRegions = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
SourceID.ToBytes(bytes, i); i += 16;
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
SearchID.ToBytes(bytes, i); i += 16;
|
|
SearchPos.ToBytes(bytes, i); i += 12;
|
|
SearchDir.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = (byte)SearchName.Length;
|
|
Buffer.BlockCopy(SearchName, 0, bytes, i, SearchName.Length); i += SearchName.Length;
|
|
Utils.IntToBytes(Type, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Range, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Arc, bytes, i); i += 4;
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
bytes[i++] = SearchRegions;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Requester.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RequesterBlock Requester;
|
|
|
|
public ScriptSensorRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ScriptSensorRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 247;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
Requester = new RequesterBlock();
|
|
}
|
|
|
|
public ScriptSensorRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Requester.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ScriptSensorRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Requester.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Requester.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Requester.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptSensorReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class RequesterBlock : PacketBlock
|
|
{
|
|
public UUID SourceID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public RequesterBlock() { }
|
|
public RequesterBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
SourceID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
SourceID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SensedDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public Vector3 Position;
|
|
public Vector3 Velocity;
|
|
public Quaternion Rotation;
|
|
public byte[] Name;
|
|
public int Type;
|
|
public float Range;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 93;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public SensedDataBlock() { }
|
|
public SensedDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
Velocity.FromBytes(bytes, i); i += 12;
|
|
Rotation.FromBytes(bytes, i, true); i += 12;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
Type = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Range = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
Velocity.ToBytes(bytes, i); i += 12;
|
|
Rotation.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
Utils.IntToBytes(Type, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Range, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += Requester.Length;
|
|
for (int j = 0; j < SensedData.Length; j++)
|
|
length += SensedData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RequesterBlock Requester;
|
|
public SensedDataBlock[] SensedData;
|
|
|
|
public ScriptSensorReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ScriptSensorReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 248;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
Requester = new RequesterBlock();
|
|
SensedData = null;
|
|
}
|
|
|
|
public ScriptSensorReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Requester.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(SensedData == null || SensedData.Length != -1) {
|
|
SensedData = new SensedDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ SensedData[j] = new SensedDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ SensedData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ScriptSensorReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Requester.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(SensedData == null || SensedData.Length != count) {
|
|
SensedData = new SensedDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ SensedData[j] = new SensedDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ SensedData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Requester.Length;
|
|
length++;
|
|
for (int j = 0; j < SensedData.Length; j++) { length += SensedData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Requester.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)SensedData.Length;
|
|
for (int j = 0; j < SensedData.Length; j++) { SensedData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += Requester.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
Requester.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int SensedDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int SensedDataCount = 0;
|
|
|
|
i = SensedDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < SensedData.Length) {
|
|
int blockLength = SensedData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == SensedDataStart) {
|
|
variableLength += blockLength;
|
|
++SensedDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)SensedDataCount;
|
|
for (i = SensedDataStart; i < SensedDataStart + SensedDataCount; i++) { SensedData[i].ToBytes(packet, ref length); }
|
|
SensedDataStart += SensedDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
SensedDataStart < SensedData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CompleteAgentMovementPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint CircuitCode;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
CircuitCode = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(CircuitCode, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public CompleteAgentMovementPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CompleteAgentMovement;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 249;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public CompleteAgentMovementPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public CompleteAgentMovementPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentMovementCompletePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public Vector3 Position;
|
|
public Vector3 LookAt;
|
|
public ulong RegionHandle;
|
|
public uint Timestamp;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
LookAt.FromBytes(bytes, i); i += 12;
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
Timestamp = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
LookAt.ToBytes(bytes, i); i += 12;
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
Utils.UIntToBytes(Timestamp, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SimDataBlock : PacketBlock
|
|
{
|
|
public byte[] ChannelVersion;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (ChannelVersion != null) { length += ChannelVersion.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public SimDataBlock() { }
|
|
public SimDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
ChannelVersion = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ChannelVersion, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(ChannelVersion.Length % 256);
|
|
bytes[i++] = (byte)((ChannelVersion.Length >> 8) % 256);
|
|
Buffer.BlockCopy(ChannelVersion, 0, bytes, i, ChannelVersion.Length); i += ChannelVersion.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
length += SimData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
public SimDataBlock SimData;
|
|
|
|
public AgentMovementCompletePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentMovementComplete;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 250;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
SimData = new SimDataBlock();
|
|
}
|
|
|
|
public AgentMovementCompletePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
SimData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentMovementCompletePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
SimData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
length += SimData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
SimData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LogoutRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public LogoutRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.LogoutRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 252;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public LogoutRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public LogoutRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LogoutReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public LogoutReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.LogoutReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 253;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public LogoutReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public LogoutReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImprovedInstantMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MessageBlockBlock : PacketBlock
|
|
{
|
|
public bool FromGroup;
|
|
public UUID ToAgentID;
|
|
public uint ParentEstateID;
|
|
public UUID RegionID;
|
|
public Vector3 Position;
|
|
public byte Offline;
|
|
public byte Dialog;
|
|
public UUID ID;
|
|
public uint Timestamp;
|
|
public byte[] FromAgentName;
|
|
public byte[] Message;
|
|
public byte[] BinaryBucket;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 76;
|
|
if (FromAgentName != null) { length += FromAgentName.Length; }
|
|
if (Message != null) { length += Message.Length; }
|
|
if (BinaryBucket != null) { length += BinaryBucket.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MessageBlockBlock() { }
|
|
public MessageBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
FromGroup = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
ToAgentID.FromBytes(bytes, i); i += 16;
|
|
ParentEstateID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RegionID.FromBytes(bytes, i); i += 16;
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
Offline = (byte)bytes[i++];
|
|
Dialog = (byte)bytes[i++];
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
Timestamp = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
FromAgentName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, FromAgentName, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
BinaryBucket = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, BinaryBucket, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((FromGroup) ? 1 : 0);
|
|
ToAgentID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(ParentEstateID, bytes, i); i += 4;
|
|
RegionID.ToBytes(bytes, i); i += 16;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = Offline;
|
|
bytes[i++] = Dialog;
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Timestamp, bytes, i); i += 4;
|
|
bytes[i++] = (byte)FromAgentName.Length;
|
|
Buffer.BlockCopy(FromAgentName, 0, bytes, i, FromAgentName.Length); i += FromAgentName.Length;
|
|
bytes[i++] = (byte)(Message.Length % 256);
|
|
bytes[i++] = (byte)((Message.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
bytes[i++] = (byte)(BinaryBucket.Length % 256);
|
|
bytes[i++] = (byte)((BinaryBucket.Length >> 8) % 256);
|
|
Buffer.BlockCopy(BinaryBucket, 0, bytes, i, BinaryBucket.Length); i += BinaryBucket.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EstateBlockBlock : PacketBlock
|
|
{
|
|
public uint EstateID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public EstateBlockBlock() { }
|
|
public EstateBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
EstateID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(EstateID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MessageBlock.Length;
|
|
length += EstateBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MessageBlockBlock MessageBlock;
|
|
public EstateBlockBlock EstateBlock;
|
|
|
|
public ImprovedInstantMessagePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ImprovedInstantMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 254;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MessageBlock = new MessageBlockBlock();
|
|
EstateBlock = new EstateBlockBlock();
|
|
}
|
|
|
|
public ImprovedInstantMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MessageBlock.FromBytes(bytes, ref i);
|
|
EstateBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ImprovedInstantMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MessageBlock.FromBytes(bytes, ref i);
|
|
EstateBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MessageBlock.Length;
|
|
length += EstateBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MessageBlock.ToBytes(bytes, ref i);
|
|
EstateBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RetrieveInstantMessagesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public RetrieveInstantMessagesPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RetrieveInstantMessages;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 255;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public RetrieveInstantMessagesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RetrieveInstantMessagesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FindAgentPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentBlockBlock : PacketBlock
|
|
{
|
|
public UUID Hunter;
|
|
public UUID Prey;
|
|
public uint SpaceIP;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentBlockBlock() { }
|
|
public AgentBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Hunter.FromBytes(bytes, i); i += 16;
|
|
Prey.FromBytes(bytes, i); i += 16;
|
|
SpaceIP = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Hunter.ToBytes(bytes, i); i += 16;
|
|
Prey.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(SpaceIP, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LocationBlockBlock : PacketBlock
|
|
{
|
|
public double GlobalX;
|
|
public double GlobalY;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public LocationBlockBlock() { }
|
|
public LocationBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GlobalX = Utils.BytesToDouble(bytes, i); i += 8;
|
|
GlobalY = Utils.BytesToDouble(bytes, i); i += 8;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.DoubleToBytes(GlobalX, bytes, i); i += 8;
|
|
Utils.DoubleToBytes(GlobalY, bytes, i); i += 8;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentBlock.Length;
|
|
for (int j = 0; j < LocationBlock.Length; j++)
|
|
length += LocationBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentBlockBlock AgentBlock;
|
|
public LocationBlockBlock[] LocationBlock;
|
|
|
|
public FindAgentPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.FindAgent;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 256;
|
|
Header.Reliable = true;
|
|
AgentBlock = new AgentBlockBlock();
|
|
LocationBlock = null;
|
|
}
|
|
|
|
public FindAgentPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(LocationBlock == null || LocationBlock.Length != -1) {
|
|
LocationBlock = new LocationBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ LocationBlock[j] = new LocationBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ LocationBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public FindAgentPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(LocationBlock == null || LocationBlock.Length != count) {
|
|
LocationBlock = new LocationBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ LocationBlock[j] = new LocationBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ LocationBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentBlock.Length;
|
|
length++;
|
|
for (int j = 0; j < LocationBlock.Length; j++) { length += LocationBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentBlock.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)LocationBlock.Length;
|
|
for (int j = 0; j < LocationBlock.Length; j++) { LocationBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentBlock.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentBlock.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int LocationBlockStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int LocationBlockCount = 0;
|
|
|
|
i = LocationBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < LocationBlock.Length) {
|
|
int blockLength = LocationBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == LocationBlockStart) {
|
|
variableLength += blockLength;
|
|
++LocationBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)LocationBlockCount;
|
|
for (i = LocationBlockStart; i < LocationBlockStart + LocationBlockCount; i++) { LocationBlock[i].ToBytes(packet, ref length); }
|
|
LocationBlockStart += LocationBlockCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
LocationBlockStart < LocationBlock.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestGodlikePowersPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestBlockBlock : PacketBlock
|
|
{
|
|
public bool Godlike;
|
|
public UUID Token;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public RequestBlockBlock() { }
|
|
public RequestBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Godlike = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Token.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((Godlike) ? 1 : 0);
|
|
Token.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RequestBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RequestBlockBlock RequestBlock;
|
|
|
|
public RequestGodlikePowersPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RequestGodlikePowers;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 257;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
RequestBlock = new RequestBlockBlock();
|
|
}
|
|
|
|
public RequestGodlikePowersPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RequestBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RequestGodlikePowersPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RequestBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RequestBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
RequestBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GrantGodlikePowersPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GrantDataBlock : PacketBlock
|
|
{
|
|
public byte GodLevel;
|
|
public UUID Token;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public GrantDataBlock() { }
|
|
public GrantDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GodLevel = (byte)bytes[i++];
|
|
Token.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = GodLevel;
|
|
Token.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GrantData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GrantDataBlock GrantData;
|
|
|
|
public GrantGodlikePowersPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GrantGodlikePowers;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 258;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GrantData = new GrantDataBlock();
|
|
}
|
|
|
|
public GrantGodlikePowersPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GrantData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GrantGodlikePowersPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GrantData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GrantData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GrantData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GodlikeMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MethodDataBlock : PacketBlock
|
|
{
|
|
public byte[] Method;
|
|
public UUID Invoice;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (Method != null) { length += Method.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MethodDataBlock() { }
|
|
public MethodDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Method = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Method, 0, length); i += length;
|
|
Invoice.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Method.Length;
|
|
Buffer.BlockCopy(Method, 0, bytes, i, Method.Length); i += Method.Length;
|
|
Invoice.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParamListBlock : PacketBlock
|
|
{
|
|
public byte[] Parameter;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (Parameter != null) { length += Parameter.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ParamListBlock() { }
|
|
public ParamListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Parameter = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Parameter, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Parameter.Length;
|
|
Buffer.BlockCopy(Parameter, 0, bytes, i, Parameter.Length); i += Parameter.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += MethodData.Length;
|
|
for (int j = 0; j < ParamList.Length; j++)
|
|
length += ParamList[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MethodDataBlock MethodData;
|
|
public ParamListBlock[] ParamList;
|
|
|
|
public GodlikeMessagePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GodlikeMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 259;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MethodData = new MethodDataBlock();
|
|
ParamList = null;
|
|
}
|
|
|
|
public GodlikeMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MethodData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParamList == null || ParamList.Length != -1) {
|
|
ParamList = new ParamListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParamList[j] = new ParamListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParamList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GodlikeMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MethodData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParamList == null || ParamList.Length != count) {
|
|
ParamList = new ParamListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParamList[j] = new ParamListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParamList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MethodData.Length;
|
|
length++;
|
|
for (int j = 0; j < ParamList.Length; j++) { length += ParamList[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MethodData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ParamList.Length;
|
|
for (int j = 0; j < ParamList.Length; j++) { ParamList[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += MethodData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
MethodData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ParamListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ParamListCount = 0;
|
|
|
|
i = ParamListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ParamList.Length) {
|
|
int blockLength = ParamList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ParamListStart) {
|
|
variableLength += blockLength;
|
|
++ParamListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ParamListCount;
|
|
for (i = ParamListStart; i < ParamListStart + ParamListCount; i++) { ParamList[i].ToBytes(packet, ref length); }
|
|
ParamListStart += ParamListCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ParamListStart < ParamList.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EstateOwnerMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MethodDataBlock : PacketBlock
|
|
{
|
|
public byte[] Method;
|
|
public UUID Invoice;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (Method != null) { length += Method.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MethodDataBlock() { }
|
|
public MethodDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Method = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Method, 0, length); i += length;
|
|
Invoice.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Method.Length;
|
|
Buffer.BlockCopy(Method, 0, bytes, i, Method.Length); i += Method.Length;
|
|
Invoice.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParamListBlock : PacketBlock
|
|
{
|
|
public byte[] Parameter;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (Parameter != null) { length += Parameter.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ParamListBlock() { }
|
|
public ParamListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Parameter = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Parameter, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Parameter.Length;
|
|
Buffer.BlockCopy(Parameter, 0, bytes, i, Parameter.Length); i += Parameter.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += MethodData.Length;
|
|
for (int j = 0; j < ParamList.Length; j++)
|
|
length += ParamList[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MethodDataBlock MethodData;
|
|
public ParamListBlock[] ParamList;
|
|
|
|
public EstateOwnerMessagePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.EstateOwnerMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 260;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MethodData = new MethodDataBlock();
|
|
ParamList = null;
|
|
}
|
|
|
|
public EstateOwnerMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MethodData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParamList == null || ParamList.Length != -1) {
|
|
ParamList = new ParamListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParamList[j] = new ParamListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParamList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public EstateOwnerMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MethodData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParamList == null || ParamList.Length != count) {
|
|
ParamList = new ParamListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParamList[j] = new ParamListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParamList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MethodData.Length;
|
|
length++;
|
|
for (int j = 0; j < ParamList.Length; j++) { length += ParamList[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MethodData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ParamList.Length;
|
|
for (int j = 0; j < ParamList.Length; j++) { ParamList[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += MethodData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
MethodData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ParamListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ParamListCount = 0;
|
|
|
|
i = ParamListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ParamList.Length) {
|
|
int blockLength = ParamList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ParamListStart) {
|
|
variableLength += blockLength;
|
|
++ParamListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ParamListCount;
|
|
for (i = ParamListStart; i < ParamListStart + ParamListCount; i++) { ParamList[i].ToBytes(packet, ref length); }
|
|
ParamListStart += ParamListCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ParamListStart < ParamList.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GenericMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MethodDataBlock : PacketBlock
|
|
{
|
|
public byte[] Method;
|
|
public UUID Invoice;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (Method != null) { length += Method.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MethodDataBlock() { }
|
|
public MethodDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Method = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Method, 0, length); i += length;
|
|
Invoice.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Method.Length;
|
|
Buffer.BlockCopy(Method, 0, bytes, i, Method.Length); i += Method.Length;
|
|
Invoice.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParamListBlock : PacketBlock
|
|
{
|
|
public byte[] Parameter;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (Parameter != null) { length += Parameter.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ParamListBlock() { }
|
|
public ParamListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Parameter = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Parameter, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Parameter.Length;
|
|
Buffer.BlockCopy(Parameter, 0, bytes, i, Parameter.Length); i += Parameter.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += MethodData.Length;
|
|
for (int j = 0; j < ParamList.Length; j++)
|
|
length += ParamList[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MethodDataBlock MethodData;
|
|
public ParamListBlock[] ParamList;
|
|
|
|
public GenericMessagePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GenericMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 261;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MethodData = new MethodDataBlock();
|
|
ParamList = null;
|
|
}
|
|
|
|
public GenericMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MethodData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParamList == null || ParamList.Length != -1) {
|
|
ParamList = new ParamListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParamList[j] = new ParamListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParamList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GenericMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MethodData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParamList == null || ParamList.Length != count) {
|
|
ParamList = new ParamListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParamList[j] = new ParamListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParamList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MethodData.Length;
|
|
length++;
|
|
for (int j = 0; j < ParamList.Length; j++) { length += ParamList[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MethodData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ParamList.Length;
|
|
for (int j = 0; j < ParamList.Length; j++) { ParamList[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += MethodData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
MethodData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ParamListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ParamListCount = 0;
|
|
|
|
i = ParamListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ParamList.Length) {
|
|
int blockLength = ParamList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ParamListStart) {
|
|
variableLength += blockLength;
|
|
++ParamListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ParamListCount;
|
|
for (i = ParamListStart; i < ParamListStart + ParamListCount; i++) { ParamList[i].ToBytes(packet, ref length); }
|
|
ParamListStart += ParamListCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ParamListStart < ParamList.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MuteListRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MuteDataBlock : PacketBlock
|
|
{
|
|
public uint MuteCRC;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public MuteDataBlock() { }
|
|
public MuteDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
MuteCRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(MuteCRC, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MuteData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MuteDataBlock MuteData;
|
|
|
|
public MuteListRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.MuteListRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 262;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
MuteData = new MuteDataBlock();
|
|
}
|
|
|
|
public MuteListRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MuteData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public MuteListRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MuteData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MuteData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MuteData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateMuteListEntryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MuteDataBlock : PacketBlock
|
|
{
|
|
public UUID MuteID;
|
|
public byte[] MuteName;
|
|
public int MuteType;
|
|
public uint MuteFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 25;
|
|
if (MuteName != null) { length += MuteName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MuteDataBlock() { }
|
|
public MuteDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
MuteID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
MuteName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MuteName, 0, length); i += length;
|
|
MuteType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
MuteFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
MuteID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)MuteName.Length;
|
|
Buffer.BlockCopy(MuteName, 0, bytes, i, MuteName.Length); i += MuteName.Length;
|
|
Utils.IntToBytes(MuteType, bytes, i); i += 4;
|
|
Utils.UIntToBytes(MuteFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MuteData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MuteDataBlock MuteData;
|
|
|
|
public UpdateMuteListEntryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.UpdateMuteListEntry;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 263;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
MuteData = new MuteDataBlock();
|
|
}
|
|
|
|
public UpdateMuteListEntryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MuteData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public UpdateMuteListEntryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MuteData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MuteData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MuteData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RemoveMuteListEntryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MuteDataBlock : PacketBlock
|
|
{
|
|
public UUID MuteID;
|
|
public byte[] MuteName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (MuteName != null) { length += MuteName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MuteDataBlock() { }
|
|
public MuteDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
MuteID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
MuteName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MuteName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
MuteID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)MuteName.Length;
|
|
Buffer.BlockCopy(MuteName, 0, bytes, i, MuteName.Length); i += MuteName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MuteData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MuteDataBlock MuteData;
|
|
|
|
public RemoveMuteListEntryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RemoveMuteListEntry;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 264;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
MuteData = new MuteDataBlock();
|
|
}
|
|
|
|
public RemoveMuteListEntryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MuteData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RemoveMuteListEntryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MuteData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MuteData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MuteData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CopyInventoryFromNotecardPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class NotecardDataBlock : PacketBlock
|
|
{
|
|
public UUID NotecardItemID;
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public NotecardDataBlock() { }
|
|
public NotecardDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
NotecardItemID.FromBytes(bytes, i); i += 16;
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
NotecardItemID.ToBytes(bytes, i); i += 16;
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += NotecardData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public NotecardDataBlock NotecardData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public CopyInventoryFromNotecardPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.CopyInventoryFromNotecard;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 265;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
NotecardData = new NotecardDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public CopyInventoryFromNotecardPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
NotecardData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public CopyInventoryFromNotecardPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
NotecardData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += NotecardData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
NotecardData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += NotecardData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
NotecardData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
public uint CallbackID;
|
|
public UUID CreatorID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public bool GroupOwned;
|
|
public UUID TransactionID;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public uint Flags;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public int CreationDate;
|
|
public uint CRC;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 142;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
CallbackID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
CreationDate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(CallbackID, bytes, i); i += 4;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((GroupOwned) ? 1 : 0);
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.IntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public UpdateInventoryItemPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.UpdateInventoryItem;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 266;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public UpdateInventoryItemPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public UpdateInventoryItemPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateCreateInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public bool SimApproved;
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SimApproved = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((SimApproved) ? 1 : 0);
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
public uint CallbackID;
|
|
public UUID CreatorID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public bool GroupOwned;
|
|
public UUID AssetID;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public uint Flags;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public int CreationDate;
|
|
public uint CRC;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 142;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
CallbackID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
AssetID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
CreationDate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(CallbackID, bytes, i); i += 4;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((GroupOwned) ? 1 : 0);
|
|
AssetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.IntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public UpdateCreateInventoryItemPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.UpdateCreateInventoryItem;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 267;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public UpdateCreateInventoryItemPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public UpdateCreateInventoryItemPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoveInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public bool Stamp;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
Stamp = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Stamp) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
public byte[] NewName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 33;
|
|
if (NewName != null) { length += NewName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
NewName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, NewName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)NewName.Length;
|
|
Buffer.BlockCopy(NewName, 0, bytes, i, NewName.Length); i += NewName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public MoveInventoryItemPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.MoveInventoryItem;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 268;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public MoveInventoryItemPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public MoveInventoryItemPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CopyInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public uint CallbackID;
|
|
public UUID OldAgentID;
|
|
public UUID OldItemID;
|
|
public UUID NewFolderID;
|
|
public byte[] NewName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 53;
|
|
if (NewName != null) { length += NewName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
CallbackID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OldAgentID.FromBytes(bytes, i); i += 16;
|
|
OldItemID.FromBytes(bytes, i); i += 16;
|
|
NewFolderID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
NewName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, NewName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(CallbackID, bytes, i); i += 4;
|
|
OldAgentID.ToBytes(bytes, i); i += 16;
|
|
OldItemID.ToBytes(bytes, i); i += 16;
|
|
NewFolderID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)NewName.Length;
|
|
Buffer.BlockCopy(NewName, 0, bytes, i, NewName.Length); i += NewName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public CopyInventoryItemPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.CopyInventoryItem;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 269;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public CopyInventoryItemPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public CopyInventoryItemPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RemoveInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public RemoveInventoryItemPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.RemoveInventoryItem;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 270;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public RemoveInventoryItemPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public RemoveInventoryItemPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChangeInventoryItemFlagsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public ChangeInventoryItemFlagsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ChangeInventoryItemFlags;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 271;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public ChangeInventoryItemFlagsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ChangeInventoryItemFlagsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SaveAssetIntoInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID NewAssetID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
NewAssetID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
NewAssetID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock InventoryData;
|
|
|
|
public SaveAssetIntoInventoryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SaveAssetIntoInventory;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 272;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = new InventoryDataBlock();
|
|
}
|
|
|
|
public SaveAssetIntoInventoryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SaveAssetIntoInventoryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
InventoryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CreateInventoryFolderPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public UUID ParentID;
|
|
public sbyte Type;
|
|
public byte[] Name;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 34;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public FolderDataBlock() { }
|
|
public FolderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
ParentID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
ParentID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += FolderData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public FolderDataBlock FolderData;
|
|
|
|
public CreateInventoryFolderPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CreateInventoryFolder;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 273;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
FolderData = new FolderDataBlock();
|
|
}
|
|
|
|
public CreateInventoryFolderPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
FolderData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public CreateInventoryFolderPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
FolderData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += FolderData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
FolderData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateInventoryFolderPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public UUID ParentID;
|
|
public sbyte Type;
|
|
public byte[] Name;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 34;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public FolderDataBlock() { }
|
|
public FolderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
ParentID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
ParentID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++)
|
|
length += FolderData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public FolderDataBlock[] FolderData;
|
|
|
|
public UpdateInventoryFolderPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.UpdateInventoryFolder;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 274;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
FolderData = null;
|
|
}
|
|
|
|
public UpdateInventoryFolderPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != -1) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public UpdateInventoryFolderPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != count) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < FolderData.Length; j++) { length += FolderData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)FolderData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int FolderDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int FolderDataCount = 0;
|
|
|
|
i = FolderDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < FolderData.Length) {
|
|
int blockLength = FolderData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == FolderDataStart) {
|
|
variableLength += blockLength;
|
|
++FolderDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)FolderDataCount;
|
|
for (i = FolderDataStart; i < FolderDataStart + FolderDataCount; i++) { FolderData[i].ToBytes(packet, ref length); }
|
|
FolderDataStart += FolderDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
FolderDataStart < FolderData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoveInventoryFolderPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public bool Stamp;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
Stamp = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Stamp) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public UUID ParentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
ParentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
ParentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public MoveInventoryFolderPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.MoveInventoryFolder;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 275;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public MoveInventoryFolderPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public MoveInventoryFolderPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RemoveInventoryFolderPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public FolderDataBlock() { }
|
|
public FolderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++)
|
|
length += FolderData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public FolderDataBlock[] FolderData;
|
|
|
|
public RemoveInventoryFolderPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.RemoveInventoryFolder;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 276;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
FolderData = null;
|
|
}
|
|
|
|
public RemoveInventoryFolderPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != -1) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public RemoveInventoryFolderPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != count) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < FolderData.Length; j++) { length += FolderData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)FolderData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int FolderDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int FolderDataCount = 0;
|
|
|
|
i = FolderDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < FolderData.Length) {
|
|
int blockLength = FolderData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == FolderDataStart) {
|
|
variableLength += blockLength;
|
|
++FolderDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)FolderDataCount;
|
|
for (i = FolderDataStart; i < FolderDataStart + FolderDataCount; i++) { FolderData[i].ToBytes(packet, ref length); }
|
|
FolderDataStart += FolderDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
FolderDataStart < FolderData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FetchInventoryDescendentsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public UUID OwnerID;
|
|
public int SortOrder;
|
|
public bool FetchFolders;
|
|
public bool FetchItems;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 38;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
SortOrder = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
FetchFolders = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
FetchItems = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(SortOrder, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((FetchFolders) ? 1 : 0);
|
|
bytes[i++] = (byte)((FetchItems) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock InventoryData;
|
|
|
|
public FetchInventoryDescendentsPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.FetchInventoryDescendents;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 277;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = new InventoryDataBlock();
|
|
}
|
|
|
|
public FetchInventoryDescendentsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public FetchInventoryDescendentsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
InventoryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDescendentsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID FolderID;
|
|
public UUID OwnerID;
|
|
public int Version;
|
|
public int Descendents;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 56;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
Version = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Descendents = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(Version, bytes, i); i += 4;
|
|
Utils.IntToBytes(Descendents, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public UUID ParentID;
|
|
public sbyte Type;
|
|
public byte[] Name;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 34;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public FolderDataBlock() { }
|
|
public FolderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
ParentID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
ParentID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ItemDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
public UUID CreatorID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public bool GroupOwned;
|
|
public UUID AssetID;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public uint Flags;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public int CreationDate;
|
|
public uint CRC;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 138;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ItemDataBlock() { }
|
|
public ItemDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
AssetID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
CreationDate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((GroupOwned) ? 1 : 0);
|
|
AssetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.IntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++)
|
|
length += FolderData[j].Length;
|
|
for (int j = 0; j < ItemData.Length; j++)
|
|
length += ItemData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public FolderDataBlock[] FolderData;
|
|
public ItemDataBlock[] ItemData;
|
|
|
|
public InventoryDescendentsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.InventoryDescendents;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 278;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
FolderData = null;
|
|
ItemData = null;
|
|
}
|
|
|
|
public InventoryDescendentsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != -1) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(ItemData == null || ItemData.Length != -1) {
|
|
ItemData = new ItemDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ItemData[j] = new ItemDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ItemData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public InventoryDescendentsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != count) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(ItemData == null || ItemData.Length != count) {
|
|
ItemData = new ItemDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ItemData[j] = new ItemDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ItemData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < FolderData.Length; j++) { length += FolderData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < ItemData.Length; j++) { length += ItemData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)FolderData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)ItemData.Length;
|
|
for (int j = 0; j < ItemData.Length; j++) { ItemData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int FolderDataStart = 0;
|
|
int ItemDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int FolderDataCount = 0;
|
|
int ItemDataCount = 0;
|
|
|
|
i = FolderDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < FolderData.Length) {
|
|
int blockLength = FolderData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == FolderDataStart) {
|
|
variableLength += blockLength;
|
|
++FolderDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = ItemDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ItemData.Length) {
|
|
int blockLength = ItemData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ItemDataStart) {
|
|
variableLength += blockLength;
|
|
++ItemDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)FolderDataCount;
|
|
for (i = FolderDataStart; i < FolderDataStart + FolderDataCount; i++) { FolderData[i].ToBytes(packet, ref length); }
|
|
FolderDataStart += FolderDataCount;
|
|
|
|
packet[length++] = (byte)ItemDataCount;
|
|
for (i = ItemDataStart; i < ItemDataStart + ItemDataCount; i++) { ItemData[i].ToBytes(packet, ref length); }
|
|
ItemDataStart += ItemDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
FolderDataStart < FolderData.Length ||
|
|
ItemDataStart < ItemData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FetchInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID OwnerID;
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public FetchInventoryPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.FetchInventory;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 279;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public FetchInventoryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public FetchInventoryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FetchInventoryReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
public UUID CreatorID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public bool GroupOwned;
|
|
public UUID AssetID;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public uint Flags;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public int CreationDate;
|
|
public uint CRC;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 138;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
AssetID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
CreationDate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((GroupOwned) ? 1 : 0);
|
|
AssetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.IntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public FetchInventoryReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.FetchInventoryReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 280;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public FetchInventoryReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public FetchInventoryReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class BulkUpdateInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public UUID ParentID;
|
|
public sbyte Type;
|
|
public byte[] Name;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 34;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public FolderDataBlock() { }
|
|
public FolderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
ParentID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
ParentID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ItemDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public uint CallbackID;
|
|
public UUID FolderID;
|
|
public UUID CreatorID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public bool GroupOwned;
|
|
public UUID AssetID;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public uint Flags;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public int CreationDate;
|
|
public uint CRC;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 142;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ItemDataBlock() { }
|
|
public ItemDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
CallbackID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
AssetID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
CreationDate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(CallbackID, bytes, i); i += 4;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((GroupOwned) ? 1 : 0);
|
|
AssetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.IntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++)
|
|
length += FolderData[j].Length;
|
|
for (int j = 0; j < ItemData.Length; j++)
|
|
length += ItemData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public FolderDataBlock[] FolderData;
|
|
public ItemDataBlock[] ItemData;
|
|
|
|
public BulkUpdateInventoryPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.BulkUpdateInventory;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 281;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
FolderData = null;
|
|
ItemData = null;
|
|
}
|
|
|
|
public BulkUpdateInventoryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != -1) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(ItemData == null || ItemData.Length != -1) {
|
|
ItemData = new ItemDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ItemData[j] = new ItemDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ItemData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public BulkUpdateInventoryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != count) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(ItemData == null || ItemData.Length != count) {
|
|
ItemData = new ItemDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ItemData[j] = new ItemDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ItemData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < FolderData.Length; j++) { length += FolderData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < ItemData.Length; j++) { length += ItemData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)FolderData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)ItemData.Length;
|
|
for (int j = 0; j < ItemData.Length; j++) { ItemData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int FolderDataStart = 0;
|
|
int ItemDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int FolderDataCount = 0;
|
|
int ItemDataCount = 0;
|
|
|
|
i = FolderDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < FolderData.Length) {
|
|
int blockLength = FolderData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == FolderDataStart) {
|
|
variableLength += blockLength;
|
|
++FolderDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = ItemDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ItemData.Length) {
|
|
int blockLength = ItemData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ItemDataStart) {
|
|
variableLength += blockLength;
|
|
++ItemDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)FolderDataCount;
|
|
for (i = FolderDataStart; i < FolderDataStart + FolderDataCount; i++) { FolderData[i].ToBytes(packet, ref length); }
|
|
FolderDataStart += FolderDataCount;
|
|
|
|
packet[length++] = (byte)ItemDataCount;
|
|
for (i = ItemDataStart; i < ItemDataStart + ItemDataCount; i++) { ItemData[i].ToBytes(packet, ref length); }
|
|
ItemDataStart += ItemDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
FolderDataStart < FolderData.Length ||
|
|
ItemDataStart < ItemData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RemoveInventoryObjectsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public FolderDataBlock() { }
|
|
public FolderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ItemDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ItemDataBlock() { }
|
|
public ItemDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++)
|
|
length += FolderData[j].Length;
|
|
for (int j = 0; j < ItemData.Length; j++)
|
|
length += ItemData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public FolderDataBlock[] FolderData;
|
|
public ItemDataBlock[] ItemData;
|
|
|
|
public RemoveInventoryObjectsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.RemoveInventoryObjects;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 284;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
FolderData = null;
|
|
ItemData = null;
|
|
}
|
|
|
|
public RemoveInventoryObjectsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != -1) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(ItemData == null || ItemData.Length != -1) {
|
|
ItemData = new ItemDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ItemData[j] = new ItemDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ItemData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public RemoveInventoryObjectsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != count) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(ItemData == null || ItemData.Length != count) {
|
|
ItemData = new ItemDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ItemData[j] = new ItemDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ItemData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < FolderData.Length; j++) { length += FolderData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < ItemData.Length; j++) { length += ItemData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)FolderData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)ItemData.Length;
|
|
for (int j = 0; j < ItemData.Length; j++) { ItemData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int FolderDataStart = 0;
|
|
int ItemDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int FolderDataCount = 0;
|
|
int ItemDataCount = 0;
|
|
|
|
i = FolderDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < FolderData.Length) {
|
|
int blockLength = FolderData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == FolderDataStart) {
|
|
variableLength += blockLength;
|
|
++FolderDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = ItemDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ItemData.Length) {
|
|
int blockLength = ItemData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ItemDataStart) {
|
|
variableLength += blockLength;
|
|
++ItemDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)FolderDataCount;
|
|
for (i = FolderDataStart; i < FolderDataStart + FolderDataCount; i++) { FolderData[i].ToBytes(packet, ref length); }
|
|
FolderDataStart += FolderDataCount;
|
|
|
|
packet[length++] = (byte)ItemDataCount;
|
|
for (i = ItemDataStart; i < ItemDataStart + ItemDataCount; i++) { ItemData[i].ToBytes(packet, ref length); }
|
|
ItemDataStart += ItemDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
FolderDataStart < FolderData.Length ||
|
|
ItemDataStart < ItemData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PurgeInventoryDescendentsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock InventoryData;
|
|
|
|
public PurgeInventoryDescendentsPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.PurgeInventoryDescendents;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 285;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = new InventoryDataBlock();
|
|
}
|
|
|
|
public PurgeInventoryDescendentsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public PurgeInventoryDescendentsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
InventoryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateTaskInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
public byte Key;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 5;
|
|
}
|
|
}
|
|
|
|
public UpdateDataBlock() { }
|
|
public UpdateDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Key = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
bytes[i++] = Key;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
public UUID CreatorID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public bool GroupOwned;
|
|
public UUID TransactionID;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public uint Flags;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public int CreationDate;
|
|
public uint CRC;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 138;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
CreationDate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((GroupOwned) ? 1 : 0);
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.IntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += UpdateData.Length;
|
|
length += InventoryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public UpdateDataBlock UpdateData;
|
|
public InventoryDataBlock InventoryData;
|
|
|
|
public UpdateTaskInventoryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.UpdateTaskInventory;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 286;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
UpdateData = new UpdateDataBlock();
|
|
InventoryData = new InventoryDataBlock();
|
|
}
|
|
|
|
public UpdateTaskInventoryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
UpdateData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public UpdateTaskInventoryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
UpdateData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += UpdateData.Length;
|
|
length += InventoryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
UpdateData.ToBytes(bytes, ref i);
|
|
InventoryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RemoveTaskInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock InventoryData;
|
|
|
|
public RemoveTaskInventoryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RemoveTaskInventory;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 287;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = new InventoryDataBlock();
|
|
}
|
|
|
|
public RemoveTaskInventoryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RemoveTaskInventoryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
InventoryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoveTaskInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID FolderID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock InventoryData;
|
|
|
|
public MoveTaskInventoryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.MoveTaskInventory;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 288;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = new InventoryDataBlock();
|
|
}
|
|
|
|
public MoveTaskInventoryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public MoveTaskInventoryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
InventoryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestTaskInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
LocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(LocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock InventoryData;
|
|
|
|
public RequestTaskInventoryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RequestTaskInventory;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 289;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = new InventoryDataBlock();
|
|
}
|
|
|
|
public RequestTaskInventoryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RequestTaskInventoryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
InventoryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ReplyTaskInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID TaskID;
|
|
public short Serial;
|
|
public byte[] Filename;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 19;
|
|
if (Filename != null) { length += Filename.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TaskID.FromBytes(bytes, i); i += 16;
|
|
Serial = (short)(bytes[i++] + (bytes[i++] << 8));
|
|
length = bytes[i++];
|
|
Filename = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Filename, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TaskID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)(Serial % 256);
|
|
bytes[i++] = (byte)((Serial >> 8) % 256);
|
|
bytes[i++] = (byte)Filename.Length;
|
|
Buffer.BlockCopy(Filename, 0, bytes, i, Filename.Length); i += Filename.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += InventoryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public InventoryDataBlock InventoryData;
|
|
|
|
public ReplyTaskInventoryPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ReplyTaskInventory;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 290;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
InventoryData = new InventoryDataBlock();
|
|
}
|
|
|
|
public ReplyTaskInventoryPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ReplyTaskInventoryPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += InventoryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
InventoryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DeRezObjectPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentBlockBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public byte Destination;
|
|
public UUID DestinationID;
|
|
public UUID TransactionID;
|
|
public byte PacketCount;
|
|
public byte PacketNumber;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 51;
|
|
}
|
|
}
|
|
|
|
public AgentBlockBlock() { }
|
|
public AgentBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
Destination = (byte)bytes[i++];
|
|
DestinationID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
PacketCount = (byte)bytes[i++];
|
|
PacketNumber = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = Destination;
|
|
DestinationID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = PacketCount;
|
|
bytes[i++] = PacketNumber;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += AgentBlock.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public AgentBlockBlock AgentBlock;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public DeRezObjectPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.DeRezObject;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 291;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
AgentBlock = new AgentBlockBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public DeRezObjectPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
AgentBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public DeRezObjectPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
AgentBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += AgentBlock.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
AgentBlock.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += AgentBlock.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
AgentBlock.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DeRezAckPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class TransactionDataBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
public bool Success;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public TransactionDataBlock() { }
|
|
public TransactionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
Success = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Success) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += TransactionData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TransactionDataBlock TransactionData;
|
|
|
|
public DeRezAckPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DeRezAck;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 292;
|
|
Header.Reliable = true;
|
|
TransactionData = new TransactionDataBlock();
|
|
}
|
|
|
|
public DeRezAckPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public DeRezAckPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TransactionData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TransactionData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RezObjectPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RezDataBlock : PacketBlock
|
|
{
|
|
public UUID FromTaskID;
|
|
public byte BypassRaycast;
|
|
public Vector3 RayStart;
|
|
public Vector3 RayEnd;
|
|
public UUID RayTargetID;
|
|
public bool RayEndIsIntersection;
|
|
public bool RezSelected;
|
|
public bool RemoveItem;
|
|
public uint ItemFlags;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 76;
|
|
}
|
|
}
|
|
|
|
public RezDataBlock() { }
|
|
public RezDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
FromTaskID.FromBytes(bytes, i); i += 16;
|
|
BypassRaycast = (byte)bytes[i++];
|
|
RayStart.FromBytes(bytes, i); i += 12;
|
|
RayEnd.FromBytes(bytes, i); i += 12;
|
|
RayTargetID.FromBytes(bytes, i); i += 16;
|
|
RayEndIsIntersection = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
RezSelected = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
RemoveItem = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
ItemFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FromTaskID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = BypassRaycast;
|
|
RayStart.ToBytes(bytes, i); i += 12;
|
|
RayEnd.ToBytes(bytes, i); i += 12;
|
|
RayTargetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((RayEndIsIntersection) ? 1 : 0);
|
|
bytes[i++] = (byte)((RezSelected) ? 1 : 0);
|
|
bytes[i++] = (byte)((RemoveItem) ? 1 : 0);
|
|
Utils.UIntToBytes(ItemFlags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
public UUID CreatorID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public bool GroupOwned;
|
|
public UUID TransactionID;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public uint Flags;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public int CreationDate;
|
|
public uint CRC;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 138;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
CreationDate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((GroupOwned) ? 1 : 0);
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.IntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RezData.Length;
|
|
length += InventoryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RezDataBlock RezData;
|
|
public InventoryDataBlock InventoryData;
|
|
|
|
public RezObjectPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RezObject;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 293;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
RezData = new RezDataBlock();
|
|
InventoryData = new InventoryDataBlock();
|
|
}
|
|
|
|
public RezObjectPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RezData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RezObjectPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RezData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RezData.Length;
|
|
length += InventoryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
RezData.ToBytes(bytes, ref i);
|
|
InventoryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RezObjectFromNotecardPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RezDataBlock : PacketBlock
|
|
{
|
|
public UUID FromTaskID;
|
|
public byte BypassRaycast;
|
|
public Vector3 RayStart;
|
|
public Vector3 RayEnd;
|
|
public UUID RayTargetID;
|
|
public bool RayEndIsIntersection;
|
|
public bool RezSelected;
|
|
public bool RemoveItem;
|
|
public uint ItemFlags;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 76;
|
|
}
|
|
}
|
|
|
|
public RezDataBlock() { }
|
|
public RezDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
FromTaskID.FromBytes(bytes, i); i += 16;
|
|
BypassRaycast = (byte)bytes[i++];
|
|
RayStart.FromBytes(bytes, i); i += 12;
|
|
RayEnd.FromBytes(bytes, i); i += 12;
|
|
RayTargetID.FromBytes(bytes, i); i += 16;
|
|
RayEndIsIntersection = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
RezSelected = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
RemoveItem = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
ItemFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FromTaskID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = BypassRaycast;
|
|
RayStart.ToBytes(bytes, i); i += 12;
|
|
RayEnd.ToBytes(bytes, i); i += 12;
|
|
RayTargetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((RayEndIsIntersection) ? 1 : 0);
|
|
bytes[i++] = (byte)((RezSelected) ? 1 : 0);
|
|
bytes[i++] = (byte)((RemoveItem) ? 1 : 0);
|
|
Utils.UIntToBytes(ItemFlags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class NotecardDataBlock : PacketBlock
|
|
{
|
|
public UUID NotecardItemID;
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public NotecardDataBlock() { }
|
|
public NotecardDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
NotecardItemID.FromBytes(bytes, i); i += 16;
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
NotecardItemID.ToBytes(bytes, i); i += 16;
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += RezData.Length;
|
|
length += NotecardData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++)
|
|
length += InventoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RezDataBlock RezData;
|
|
public NotecardDataBlock NotecardData;
|
|
public InventoryDataBlock[] InventoryData;
|
|
|
|
public RezObjectFromNotecardPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.RezObjectFromNotecard;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 294;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
RezData = new RezDataBlock();
|
|
NotecardData = new NotecardDataBlock();
|
|
InventoryData = null;
|
|
}
|
|
|
|
public RezObjectFromNotecardPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RezData.FromBytes(bytes, ref i);
|
|
NotecardData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != -1) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public RezObjectFromNotecardPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RezData.FromBytes(bytes, ref i);
|
|
NotecardData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InventoryData == null || InventoryData.Length != count) {
|
|
InventoryData = new InventoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InventoryData[j] = new InventoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InventoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RezData.Length;
|
|
length += NotecardData.Length;
|
|
length++;
|
|
for (int j = 0; j < InventoryData.Length; j++) { length += InventoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
RezData.ToBytes(bytes, ref i);
|
|
NotecardData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InventoryData.Length;
|
|
for (int j = 0; j < InventoryData.Length; j++) { InventoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += RezData.Length;
|
|
fixedLength += NotecardData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
RezData.ToBytes(fixedBytes, ref i);
|
|
NotecardData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InventoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InventoryDataCount = 0;
|
|
|
|
i = InventoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InventoryData.Length) {
|
|
int blockLength = InventoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InventoryDataStart) {
|
|
variableLength += blockLength;
|
|
++InventoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InventoryDataCount;
|
|
for (i = InventoryDataStart; i < InventoryDataStart + InventoryDataCount; i++) { InventoryData[i].ToBytes(packet, ref length); }
|
|
InventoryDataStart += InventoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InventoryDataStart < InventoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AcceptFriendshipPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionBlockBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TransactionBlockBlock() { }
|
|
public TransactionBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public FolderDataBlock() { }
|
|
public FolderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += TransactionBlock.Length;
|
|
for (int j = 0; j < FolderData.Length; j++)
|
|
length += FolderData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public TransactionBlockBlock TransactionBlock;
|
|
public FolderDataBlock[] FolderData;
|
|
|
|
public AcceptFriendshipPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AcceptFriendship;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 297;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
TransactionBlock = new TransactionBlockBlock();
|
|
FolderData = null;
|
|
}
|
|
|
|
public AcceptFriendshipPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != -1) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AcceptFriendshipPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != count) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionBlock.Length;
|
|
length++;
|
|
for (int j = 0; j < FolderData.Length; j++) { length += FolderData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TransactionBlock.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)FolderData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += TransactionBlock.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
TransactionBlock.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int FolderDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int FolderDataCount = 0;
|
|
|
|
i = FolderDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < FolderData.Length) {
|
|
int blockLength = FolderData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == FolderDataStart) {
|
|
variableLength += blockLength;
|
|
++FolderDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)FolderDataCount;
|
|
for (i = FolderDataStart; i < FolderDataStart + FolderDataCount; i++) { FolderData[i].ToBytes(packet, ref length); }
|
|
FolderDataStart += FolderDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
FolderDataStart < FolderData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DeclineFriendshipPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionBlockBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TransactionBlockBlock() { }
|
|
public TransactionBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public TransactionBlockBlock TransactionBlock;
|
|
|
|
public DeclineFriendshipPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DeclineFriendship;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 298;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
TransactionBlock = new TransactionBlockBlock();
|
|
}
|
|
|
|
public DeclineFriendshipPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public DeclineFriendshipPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TransactionBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TerminateFriendshipPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ExBlockBlock : PacketBlock
|
|
{
|
|
public UUID OtherID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ExBlockBlock() { }
|
|
public ExBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
OtherID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
OtherID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ExBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ExBlockBlock ExBlock;
|
|
|
|
public TerminateFriendshipPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TerminateFriendship;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 300;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ExBlock = new ExBlockBlock();
|
|
}
|
|
|
|
public TerminateFriendshipPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ExBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TerminateFriendshipPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ExBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ExBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ExBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class OfferCallingCardPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentBlockBlock : PacketBlock
|
|
{
|
|
public UUID DestID;
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentBlockBlock() { }
|
|
public AgentBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
DestID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
DestID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += AgentBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public AgentBlockBlock AgentBlock;
|
|
|
|
public OfferCallingCardPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.OfferCallingCard;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 301;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
AgentBlock = new AgentBlockBlock();
|
|
}
|
|
|
|
public OfferCallingCardPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
AgentBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public OfferCallingCardPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
AgentBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += AgentBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
AgentBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AcceptCallingCardPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionBlockBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TransactionBlockBlock() { }
|
|
public TransactionBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public FolderDataBlock() { }
|
|
public FolderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += TransactionBlock.Length;
|
|
for (int j = 0; j < FolderData.Length; j++)
|
|
length += FolderData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public TransactionBlockBlock TransactionBlock;
|
|
public FolderDataBlock[] FolderData;
|
|
|
|
public AcceptCallingCardPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AcceptCallingCard;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 302;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
TransactionBlock = new TransactionBlockBlock();
|
|
FolderData = null;
|
|
}
|
|
|
|
public AcceptCallingCardPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != -1) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AcceptCallingCardPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionBlock.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(FolderData == null || FolderData.Length != count) {
|
|
FolderData = new FolderDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ FolderData[j] = new FolderDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ FolderData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionBlock.Length;
|
|
length++;
|
|
for (int j = 0; j < FolderData.Length; j++) { length += FolderData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TransactionBlock.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)FolderData.Length;
|
|
for (int j = 0; j < FolderData.Length; j++) { FolderData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += TransactionBlock.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
TransactionBlock.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int FolderDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int FolderDataCount = 0;
|
|
|
|
i = FolderDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < FolderData.Length) {
|
|
int blockLength = FolderData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == FolderDataStart) {
|
|
variableLength += blockLength;
|
|
++FolderDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)FolderDataCount;
|
|
for (i = FolderDataStart; i < FolderDataStart + FolderDataCount; i++) { FolderData[i].ToBytes(packet, ref length); }
|
|
FolderDataStart += FolderDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
FolderDataStart < FolderData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DeclineCallingCardPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionBlockBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TransactionBlockBlock() { }
|
|
public TransactionBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public TransactionBlockBlock TransactionBlock;
|
|
|
|
public DeclineCallingCardPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DeclineCallingCard;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 303;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
TransactionBlock = new TransactionBlockBlock();
|
|
}
|
|
|
|
public DeclineCallingCardPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public DeclineCallingCardPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TransactionBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RezScriptPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateBlockBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public bool Enabled;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 5;
|
|
}
|
|
}
|
|
|
|
public UpdateBlockBlock() { }
|
|
public UpdateBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Enabled = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((Enabled) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryBlockBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
public UUID CreatorID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public bool GroupOwned;
|
|
public UUID TransactionID;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public uint Flags;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public int CreationDate;
|
|
public uint CRC;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 138;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryBlockBlock() { }
|
|
public InventoryBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
CreationDate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((GroupOwned) ? 1 : 0);
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.IntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += UpdateBlock.Length;
|
|
length += InventoryBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public UpdateBlockBlock UpdateBlock;
|
|
public InventoryBlockBlock InventoryBlock;
|
|
|
|
public RezScriptPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RezScript;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 304;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
UpdateBlock = new UpdateBlockBlock();
|
|
InventoryBlock = new InventoryBlockBlock();
|
|
}
|
|
|
|
public RezScriptPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
UpdateBlock.FromBytes(bytes, ref i);
|
|
InventoryBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RezScriptPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
UpdateBlock.FromBytes(bytes, ref i);
|
|
InventoryBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += UpdateBlock.Length;
|
|
length += InventoryBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
UpdateBlock.ToBytes(bytes, ref i);
|
|
InventoryBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CreateInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryBlockBlock : PacketBlock
|
|
{
|
|
public uint CallbackID;
|
|
public UUID FolderID;
|
|
public UUID TransactionID;
|
|
public uint NextOwnerMask;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public byte WearableType;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 45;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryBlockBlock() { }
|
|
public InventoryBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
CallbackID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
WearableType = (byte)bytes[i++];
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(CallbackID, bytes, i); i += 4;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
bytes[i++] = WearableType;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryBlockBlock InventoryBlock;
|
|
|
|
public CreateInventoryItemPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CreateInventoryItem;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 305;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryBlock = new InventoryBlockBlock();
|
|
}
|
|
|
|
public CreateInventoryItemPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public CreateInventoryItemPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
InventoryBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CreateLandmarkForEventPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventDataBlock : PacketBlock
|
|
{
|
|
public uint EventID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public EventDataBlock() { }
|
|
public EventDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
EventID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(EventID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryBlockBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public byte[] Name;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryBlockBlock() { }
|
|
public InventoryBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
length += InventoryBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public EventDataBlock EventData;
|
|
public InventoryBlockBlock InventoryBlock;
|
|
|
|
public CreateLandmarkForEventPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CreateLandmarkForEvent;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 306;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
EventData = new EventDataBlock();
|
|
InventoryBlock = new InventoryBlockBlock();
|
|
}
|
|
|
|
public CreateLandmarkForEventPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
InventoryBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public CreateLandmarkForEventPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
EventData.FromBytes(bytes, ref i);
|
|
InventoryBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += EventData.Length;
|
|
length += InventoryBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
EventData.ToBytes(bytes, ref i);
|
|
InventoryBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionHandleRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class RequestBlockBlock : PacketBlock
|
|
{
|
|
public UUID RegionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public RequestBlockBlock() { }
|
|
public RequestBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RegionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += RequestBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RequestBlockBlock RequestBlock;
|
|
|
|
public RegionHandleRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RegionHandleRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 309;
|
|
Header.Reliable = true;
|
|
RequestBlock = new RequestBlockBlock();
|
|
}
|
|
|
|
public RegionHandleRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
RequestBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RegionHandleRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
RequestBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += RequestBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RequestBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionIDAndHandleReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ReplyBlockBlock : PacketBlock
|
|
{
|
|
public UUID RegionID;
|
|
public ulong RegionHandle;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 24;
|
|
}
|
|
}
|
|
|
|
public ReplyBlockBlock() { }
|
|
public ReplyBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionID.FromBytes(bytes, i); i += 16;
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RegionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += ReplyBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ReplyBlockBlock ReplyBlock;
|
|
|
|
public RegionIDAndHandleReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RegionIDAndHandleReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 310;
|
|
Header.Reliable = true;
|
|
ReplyBlock = new ReplyBlockBlock();
|
|
}
|
|
|
|
public RegionIDAndHandleReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ReplyBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RegionIDAndHandleReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ReplyBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += ReplyBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ReplyBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyTransferRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID SourceID;
|
|
public UUID DestID;
|
|
public byte Flags;
|
|
public int Amount;
|
|
public byte AggregatePermNextOwner;
|
|
public byte AggregatePermInventory;
|
|
public int TransactionType;
|
|
public byte[] Description;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 44;
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MoneyDataBlock() { }
|
|
public MoneyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
SourceID.FromBytes(bytes, i); i += 16;
|
|
DestID.FromBytes(bytes, i); i += 16;
|
|
Flags = (byte)bytes[i++];
|
|
Amount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
AggregatePermNextOwner = (byte)bytes[i++];
|
|
AggregatePermInventory = (byte)bytes[i++];
|
|
TransactionType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
SourceID.ToBytes(bytes, i); i += 16;
|
|
DestID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = Flags;
|
|
Utils.IntToBytes(Amount, bytes, i); i += 4;
|
|
bytes[i++] = AggregatePermNextOwner;
|
|
bytes[i++] = AggregatePermInventory;
|
|
Utils.IntToBytes(TransactionType, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MoneyDataBlock MoneyData;
|
|
|
|
public MoneyTransferRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.MoneyTransferRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 311;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MoneyData = new MoneyDataBlock();
|
|
}
|
|
|
|
public MoneyTransferRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public MoneyTransferRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MoneyData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyBalanceRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public MoneyDataBlock() { }
|
|
public MoneyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MoneyDataBlock MoneyData;
|
|
|
|
public MoneyBalanceRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.MoneyBalanceRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 313;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MoneyData = new MoneyDataBlock();
|
|
}
|
|
|
|
public MoneyBalanceRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public MoneyBalanceRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MoneyData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyBalanceReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID TransactionID;
|
|
public bool TransactionSuccess;
|
|
public int MoneyBalance;
|
|
public int SquareMetersCredit;
|
|
public int SquareMetersCommitted;
|
|
public byte[] Description;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 46;
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MoneyDataBlock() { }
|
|
public MoneyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
TransactionSuccess = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
MoneyBalance = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SquareMetersCredit = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SquareMetersCommitted = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((TransactionSuccess) ? 1 : 0);
|
|
Utils.IntToBytes(MoneyBalance, bytes, i); i += 4;
|
|
Utils.IntToBytes(SquareMetersCredit, bytes, i); i += 4;
|
|
Utils.IntToBytes(SquareMetersCommitted, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionInfoBlock : PacketBlock
|
|
{
|
|
public int TransactionType;
|
|
public UUID SourceID;
|
|
public bool IsSourceGroup;
|
|
public UUID DestID;
|
|
public bool IsDestGroup;
|
|
public int Amount;
|
|
public byte[] ItemDescription;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 43;
|
|
if (ItemDescription != null) { length += ItemDescription.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public TransactionInfoBlock() { }
|
|
public TransactionInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TransactionType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SourceID.FromBytes(bytes, i); i += 16;
|
|
IsSourceGroup = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
DestID.FromBytes(bytes, i); i += 16;
|
|
IsDestGroup = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Amount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
ItemDescription = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ItemDescription, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(TransactionType, bytes, i); i += 4;
|
|
SourceID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsSourceGroup) ? 1 : 0);
|
|
DestID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsDestGroup) ? 1 : 0);
|
|
Utils.IntToBytes(Amount, bytes, i); i += 4;
|
|
bytes[i++] = (byte)ItemDescription.Length;
|
|
Buffer.BlockCopy(ItemDescription, 0, bytes, i, ItemDescription.Length); i += ItemDescription.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += MoneyData.Length;
|
|
length += TransactionInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public MoneyDataBlock MoneyData;
|
|
public TransactionInfoBlock TransactionInfo;
|
|
|
|
public MoneyBalanceReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.MoneyBalanceReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 314;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
MoneyData = new MoneyDataBlock();
|
|
TransactionInfo = new TransactionInfoBlock();
|
|
}
|
|
|
|
public MoneyBalanceReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
TransactionInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public MoneyBalanceReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
TransactionInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += MoneyData.Length;
|
|
length += TransactionInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
MoneyData.ToBytes(bytes, ref i);
|
|
TransactionInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RoutedMoneyBalanceReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class TargetBlockBlock : PacketBlock
|
|
{
|
|
public uint TargetIP;
|
|
public ushort TargetPort;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 6;
|
|
}
|
|
}
|
|
|
|
public TargetBlockBlock() { }
|
|
public TargetBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TargetIP = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TargetPort = (ushort)((bytes[i++] << 8) + bytes[i++]);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(TargetIP, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((TargetPort >> 8) % 256);
|
|
bytes[i++] = (byte)(TargetPort % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID TransactionID;
|
|
public bool TransactionSuccess;
|
|
public int MoneyBalance;
|
|
public int SquareMetersCredit;
|
|
public int SquareMetersCommitted;
|
|
public byte[] Description;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 46;
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MoneyDataBlock() { }
|
|
public MoneyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
TransactionSuccess = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
MoneyBalance = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SquareMetersCredit = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SquareMetersCommitted = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((TransactionSuccess) ? 1 : 0);
|
|
Utils.IntToBytes(MoneyBalance, bytes, i); i += 4;
|
|
Utils.IntToBytes(SquareMetersCredit, bytes, i); i += 4;
|
|
Utils.IntToBytes(SquareMetersCommitted, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionInfoBlock : PacketBlock
|
|
{
|
|
public int TransactionType;
|
|
public UUID SourceID;
|
|
public bool IsSourceGroup;
|
|
public UUID DestID;
|
|
public bool IsDestGroup;
|
|
public int Amount;
|
|
public byte[] ItemDescription;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 43;
|
|
if (ItemDescription != null) { length += ItemDescription.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public TransactionInfoBlock() { }
|
|
public TransactionInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TransactionType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SourceID.FromBytes(bytes, i); i += 16;
|
|
IsSourceGroup = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
DestID.FromBytes(bytes, i); i += 16;
|
|
IsDestGroup = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Amount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
ItemDescription = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ItemDescription, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(TransactionType, bytes, i); i += 4;
|
|
SourceID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsSourceGroup) ? 1 : 0);
|
|
DestID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsDestGroup) ? 1 : 0);
|
|
Utils.IntToBytes(Amount, bytes, i); i += 4;
|
|
bytes[i++] = (byte)ItemDescription.Length;
|
|
Buffer.BlockCopy(ItemDescription, 0, bytes, i, ItemDescription.Length); i += ItemDescription.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += TargetBlock.Length;
|
|
length += MoneyData.Length;
|
|
length += TransactionInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TargetBlockBlock TargetBlock;
|
|
public MoneyDataBlock MoneyData;
|
|
public TransactionInfoBlock TransactionInfo;
|
|
|
|
public RoutedMoneyBalanceReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RoutedMoneyBalanceReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 315;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
TargetBlock = new TargetBlockBlock();
|
|
MoneyData = new MoneyDataBlock();
|
|
TransactionInfo = new TransactionInfoBlock();
|
|
}
|
|
|
|
public RoutedMoneyBalanceReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TargetBlock.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
TransactionInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RoutedMoneyBalanceReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TargetBlock.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
TransactionInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TargetBlock.Length;
|
|
length += MoneyData.Length;
|
|
length += TransactionInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TargetBlock.ToBytes(bytes, ref i);
|
|
MoneyData.ToBytes(bytes, ref i);
|
|
TransactionInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ActivateGesturesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID AssetID;
|
|
public uint GestureFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
AssetID.FromBytes(bytes, i); i += 16;
|
|
GestureFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
AssetID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(GestureFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock[] Data;
|
|
|
|
public ActivateGesturesPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ActivateGestures;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 316;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = null;
|
|
}
|
|
|
|
public ActivateGesturesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ActivateGesturesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DeactivateGesturesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public uint GestureFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
GestureFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(GestureFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock[] Data;
|
|
|
|
public DeactivateGesturesPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.DeactivateGestures;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 317;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = null;
|
|
}
|
|
|
|
public DeactivateGesturesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public DeactivateGesturesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MuteListUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class MuteDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public byte[] Filename;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (Filename != null) { length += Filename.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MuteDataBlock() { }
|
|
public MuteDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Filename = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Filename, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Filename.Length;
|
|
Buffer.BlockCopy(Filename, 0, bytes, i, Filename.Length); i += Filename.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += MuteData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public MuteDataBlock MuteData;
|
|
|
|
public MuteListUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.MuteListUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 318;
|
|
Header.Reliable = true;
|
|
MuteData = new MuteDataBlock();
|
|
}
|
|
|
|
public MuteListUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
MuteData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public MuteListUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
MuteData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += MuteData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
MuteData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UseCachedMuteListPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public UseCachedMuteListPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.UseCachedMuteList;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 319;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public UseCachedMuteListPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public UseCachedMuteListPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GrantUserRightsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RightsBlock : PacketBlock
|
|
{
|
|
public UUID AgentRelated;
|
|
public int RelatedRights;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public RightsBlock() { }
|
|
public RightsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentRelated.FromBytes(bytes, i); i += 16;
|
|
RelatedRights = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentRelated.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(RelatedRights, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < Rights.Length; j++)
|
|
length += Rights[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RightsBlock[] Rights;
|
|
|
|
public GrantUserRightsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GrantUserRights;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 320;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Rights = null;
|
|
}
|
|
|
|
public GrantUserRightsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Rights == null || Rights.Length != -1) {
|
|
Rights = new RightsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Rights[j] = new RightsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Rights[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GrantUserRightsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Rights == null || Rights.Length != count) {
|
|
Rights = new RightsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Rights[j] = new RightsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Rights[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < Rights.Length; j++) { length += Rights[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Rights.Length;
|
|
for (int j = 0; j < Rights.Length; j++) { Rights[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int RightsStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int RightsCount = 0;
|
|
|
|
i = RightsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Rights.Length) {
|
|
int blockLength = Rights[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == RightsStart) {
|
|
variableLength += blockLength;
|
|
++RightsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)RightsCount;
|
|
for (i = RightsStart; i < RightsStart + RightsCount; i++) { Rights[i].ToBytes(packet, ref length); }
|
|
RightsStart += RightsCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
RightsStart < Rights.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChangeUserRightsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RightsBlock : PacketBlock
|
|
{
|
|
public UUID AgentRelated;
|
|
public int RelatedRights;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public RightsBlock() { }
|
|
public RightsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentRelated.FromBytes(bytes, i); i += 16;
|
|
RelatedRights = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentRelated.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(RelatedRights, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < Rights.Length; j++)
|
|
length += Rights[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RightsBlock[] Rights;
|
|
|
|
public ChangeUserRightsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ChangeUserRights;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 321;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Rights = null;
|
|
}
|
|
|
|
public ChangeUserRightsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Rights == null || Rights.Length != -1) {
|
|
Rights = new RightsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Rights[j] = new RightsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Rights[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ChangeUserRightsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Rights == null || Rights.Length != count) {
|
|
Rights = new RightsBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Rights[j] = new RightsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Rights[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < Rights.Length; j++) { length += Rights[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Rights.Length;
|
|
for (int j = 0; j < Rights.Length; j++) { Rights[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int RightsStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int RightsCount = 0;
|
|
|
|
i = RightsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Rights.Length) {
|
|
int blockLength = Rights[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == RightsStart) {
|
|
variableLength += blockLength;
|
|
++RightsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)RightsCount;
|
|
for (i = RightsStart; i < RightsStart + RightsCount; i++) { Rights[i].ToBytes(packet, ref length); }
|
|
RightsStart += RightsCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
RightsStart < Rights.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class OnlineNotificationPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentBlockBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentBlockBlock() { }
|
|
public AgentBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < AgentBlock.Length; j++)
|
|
length += AgentBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentBlockBlock[] AgentBlock;
|
|
|
|
public OnlineNotificationPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.OnlineNotification;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 322;
|
|
Header.Reliable = true;
|
|
AgentBlock = null;
|
|
}
|
|
|
|
public OnlineNotificationPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(AgentBlock == null || AgentBlock.Length != -1) {
|
|
AgentBlock = new AgentBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentBlock[j] = new AgentBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public OnlineNotificationPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(AgentBlock == null || AgentBlock.Length != count) {
|
|
AgentBlock = new AgentBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentBlock[j] = new AgentBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < AgentBlock.Length; j++) { length += AgentBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AgentBlock.Length;
|
|
for (int j = 0; j < AgentBlock.Length; j++) { AgentBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int AgentBlockStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int AgentBlockCount = 0;
|
|
|
|
i = AgentBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AgentBlock.Length) {
|
|
int blockLength = AgentBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AgentBlockStart) {
|
|
variableLength += blockLength;
|
|
++AgentBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)AgentBlockCount;
|
|
for (i = AgentBlockStart; i < AgentBlockStart + AgentBlockCount; i++) { AgentBlock[i].ToBytes(packet, ref length); }
|
|
AgentBlockStart += AgentBlockCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
AgentBlockStart < AgentBlock.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class OfflineNotificationPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentBlockBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentBlockBlock() { }
|
|
public AgentBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < AgentBlock.Length; j++)
|
|
length += AgentBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentBlockBlock[] AgentBlock;
|
|
|
|
public OfflineNotificationPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.OfflineNotification;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 323;
|
|
Header.Reliable = true;
|
|
AgentBlock = null;
|
|
}
|
|
|
|
public OfflineNotificationPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(AgentBlock == null || AgentBlock.Length != -1) {
|
|
AgentBlock = new AgentBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentBlock[j] = new AgentBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public OfflineNotificationPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(AgentBlock == null || AgentBlock.Length != count) {
|
|
AgentBlock = new AgentBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentBlock[j] = new AgentBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < AgentBlock.Length; j++) { length += AgentBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AgentBlock.Length;
|
|
for (int j = 0; j < AgentBlock.Length; j++) { AgentBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int AgentBlockStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int AgentBlockCount = 0;
|
|
|
|
i = AgentBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AgentBlock.Length) {
|
|
int blockLength = AgentBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AgentBlockStart) {
|
|
variableLength += blockLength;
|
|
++AgentBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)AgentBlockCount;
|
|
for (i = AgentBlockStart; i < AgentBlockStart + AgentBlockCount; i++) { AgentBlock[i].ToBytes(packet, ref length); }
|
|
AgentBlockStart += AgentBlockCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
AgentBlockStart < AgentBlock.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SetStartLocationRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StartLocationDataBlock : PacketBlock
|
|
{
|
|
public byte[] SimName;
|
|
public uint LocationID;
|
|
public Vector3 LocationPos;
|
|
public Vector3 LocationLookAt;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 29;
|
|
if (SimName != null) { length += SimName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public StartLocationDataBlock() { }
|
|
public StartLocationDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
SimName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimName, 0, length); i += length;
|
|
LocationID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LocationPos.FromBytes(bytes, i); i += 12;
|
|
LocationLookAt.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)SimName.Length;
|
|
Buffer.BlockCopy(SimName, 0, bytes, i, SimName.Length); i += SimName.Length;
|
|
Utils.UIntToBytes(LocationID, bytes, i); i += 4;
|
|
LocationPos.ToBytes(bytes, i); i += 12;
|
|
LocationLookAt.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += StartLocationData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public StartLocationDataBlock StartLocationData;
|
|
|
|
public SetStartLocationRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SetStartLocationRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 324;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
StartLocationData = new StartLocationDataBlock();
|
|
}
|
|
|
|
public SetStartLocationRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
StartLocationData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SetStartLocationRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
StartLocationData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += StartLocationData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
StartLocationData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AssetUploadRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AssetBlockBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
public sbyte Type;
|
|
public bool Tempfile;
|
|
public bool StoreLocal;
|
|
public byte[] AssetData;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 21;
|
|
if (AssetData != null) { length += AssetData.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AssetBlockBlock() { }
|
|
public AssetBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
Tempfile = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
StoreLocal = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
AssetData = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, AssetData, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)((Tempfile) ? 1 : 0);
|
|
bytes[i++] = (byte)((StoreLocal) ? 1 : 0);
|
|
bytes[i++] = (byte)(AssetData.Length % 256);
|
|
bytes[i++] = (byte)((AssetData.Length >> 8) % 256);
|
|
Buffer.BlockCopy(AssetData, 0, bytes, i, AssetData.Length); i += AssetData.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AssetBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AssetBlockBlock AssetBlock;
|
|
|
|
public AssetUploadRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AssetUploadRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 333;
|
|
Header.Reliable = true;
|
|
AssetBlock = new AssetBlockBlock();
|
|
}
|
|
|
|
public AssetUploadRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AssetBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AssetUploadRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AssetBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AssetBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AssetBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AssetUploadCompletePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AssetBlockBlock : PacketBlock
|
|
{
|
|
public UUID UUID;
|
|
public sbyte Type;
|
|
public bool Success;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 18;
|
|
}
|
|
}
|
|
|
|
public AssetBlockBlock() { }
|
|
public AssetBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
UUID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
Success = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
UUID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)((Success) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AssetBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AssetBlockBlock AssetBlock;
|
|
|
|
public AssetUploadCompletePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AssetUploadComplete;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 334;
|
|
Header.Reliable = true;
|
|
AssetBlock = new AssetBlockBlock();
|
|
}
|
|
|
|
public AssetUploadCompletePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AssetBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AssetUploadCompletePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AssetBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AssetBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AssetBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CreateGroupRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public byte[] Name;
|
|
public byte[] Charter;
|
|
public bool ShowInList;
|
|
public UUID InsigniaID;
|
|
public int MembershipFee;
|
|
public bool OpenEnrollment;
|
|
public bool AllowPublish;
|
|
public bool MaturePublish;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 27;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Charter != null) { length += Charter.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Charter = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Charter, 0, length); i += length;
|
|
ShowInList = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
InsigniaID.FromBytes(bytes, i); i += 16;
|
|
MembershipFee = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OpenEnrollment = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)(Charter.Length % 256);
|
|
bytes[i++] = (byte)((Charter.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Charter, 0, bytes, i, Charter.Length); i += Charter.Length;
|
|
bytes[i++] = (byte)((ShowInList) ? 1 : 0);
|
|
InsigniaID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(MembershipFee, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((OpenEnrollment) ? 1 : 0);
|
|
bytes[i++] = (byte)((AllowPublish) ? 1 : 0);
|
|
bytes[i++] = (byte)((MaturePublish) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public CreateGroupRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CreateGroupRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 339;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public CreateGroupRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public CreateGroupRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CreateGroupReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ReplyDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public bool Success;
|
|
public byte[] Message;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 18;
|
|
if (Message != null) { length += Message.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ReplyDataBlock() { }
|
|
public ReplyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
Success = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = bytes[i++];
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Success) ? 1 : 0);
|
|
bytes[i++] = (byte)Message.Length;
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ReplyData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ReplyDataBlock ReplyData;
|
|
|
|
public CreateGroupReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CreateGroupReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 340;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ReplyData = new ReplyDataBlock();
|
|
}
|
|
|
|
public CreateGroupReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ReplyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public CreateGroupReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ReplyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ReplyData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ReplyData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateGroupInfoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public byte[] Charter;
|
|
public bool ShowInList;
|
|
public UUID InsigniaID;
|
|
public int MembershipFee;
|
|
public bool OpenEnrollment;
|
|
public bool AllowPublish;
|
|
public bool MaturePublish;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 42;
|
|
if (Charter != null) { length += Charter.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Charter = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Charter, 0, length); i += length;
|
|
ShowInList = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
InsigniaID.FromBytes(bytes, i); i += 16;
|
|
MembershipFee = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OpenEnrollment = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)(Charter.Length % 256);
|
|
bytes[i++] = (byte)((Charter.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Charter, 0, bytes, i, Charter.Length); i += Charter.Length;
|
|
bytes[i++] = (byte)((ShowInList) ? 1 : 0);
|
|
InsigniaID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(MembershipFee, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((OpenEnrollment) ? 1 : 0);
|
|
bytes[i++] = (byte)((AllowPublish) ? 1 : 0);
|
|
bytes[i++] = (byte)((MaturePublish) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public UpdateGroupInfoPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.UpdateGroupInfo;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 341;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public UpdateGroupInfoPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public UpdateGroupInfoPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupRoleChangesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RoleChangeBlock : PacketBlock
|
|
{
|
|
public UUID RoleID;
|
|
public UUID MemberID;
|
|
public uint Change;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public RoleChangeBlock() { }
|
|
public RoleChangeBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RoleID.FromBytes(bytes, i); i += 16;
|
|
MemberID.FromBytes(bytes, i); i += 16;
|
|
Change = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RoleID.ToBytes(bytes, i); i += 16;
|
|
MemberID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Change, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < RoleChange.Length; j++)
|
|
length += RoleChange[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RoleChangeBlock[] RoleChange;
|
|
|
|
public GroupRoleChangesPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupRoleChanges;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 342;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
RoleChange = null;
|
|
}
|
|
|
|
public GroupRoleChangesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RoleChange == null || RoleChange.Length != -1) {
|
|
RoleChange = new RoleChangeBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RoleChange[j] = new RoleChangeBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RoleChange[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupRoleChangesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RoleChange == null || RoleChange.Length != count) {
|
|
RoleChange = new RoleChangeBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RoleChange[j] = new RoleChangeBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RoleChange[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < RoleChange.Length; j++) { length += RoleChange[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)RoleChange.Length;
|
|
for (int j = 0; j < RoleChange.Length; j++) { RoleChange[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int RoleChangeStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int RoleChangeCount = 0;
|
|
|
|
i = RoleChangeStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < RoleChange.Length) {
|
|
int blockLength = RoleChange[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == RoleChangeStart) {
|
|
variableLength += blockLength;
|
|
++RoleChangeCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)RoleChangeCount;
|
|
for (i = RoleChangeStart; i < RoleChangeStart + RoleChangeCount; i++) { RoleChange[i].ToBytes(packet, ref length); }
|
|
RoleChangeStart += RoleChangeCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
RoleChangeStart < RoleChange.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class JoinGroupRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public JoinGroupRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.JoinGroupRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 343;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public JoinGroupRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public JoinGroupRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class JoinGroupReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public bool Success;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
Success = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Success) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public JoinGroupReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.JoinGroupReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 344;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public JoinGroupReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public JoinGroupReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EjectGroupMemberRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EjectDataBlock : PacketBlock
|
|
{
|
|
public UUID EjecteeID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public EjectDataBlock() { }
|
|
public EjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
EjecteeID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
EjecteeID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
for (int j = 0; j < EjectData.Length; j++)
|
|
length += EjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
public EjectDataBlock[] EjectData;
|
|
|
|
public EjectGroupMemberRequestPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.EjectGroupMemberRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 345;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
EjectData = null;
|
|
}
|
|
|
|
public EjectGroupMemberRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(EjectData == null || EjectData.Length != -1) {
|
|
EjectData = new EjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ EjectData[j] = new EjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ EjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public EjectGroupMemberRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(EjectData == null || EjectData.Length != count) {
|
|
EjectData = new EjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ EjectData[j] = new EjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ EjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
length++;
|
|
for (int j = 0; j < EjectData.Length; j++) { length += EjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)EjectData.Length;
|
|
for (int j = 0; j < EjectData.Length; j++) { EjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += GroupData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
GroupData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int EjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int EjectDataCount = 0;
|
|
|
|
i = EjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < EjectData.Length) {
|
|
int blockLength = EjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == EjectDataStart) {
|
|
variableLength += blockLength;
|
|
++EjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)EjectDataCount;
|
|
for (i = EjectDataStart; i < EjectDataStart + EjectDataCount; i++) { EjectData[i].ToBytes(packet, ref length); }
|
|
EjectDataStart += EjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
EjectDataStart < EjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EjectGroupMemberReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EjectDataBlock : PacketBlock
|
|
{
|
|
public bool Success;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public EjectDataBlock() { }
|
|
public EjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Success = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((Success) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
length += EjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
public EjectDataBlock EjectData;
|
|
|
|
public EjectGroupMemberReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.EjectGroupMemberReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 346;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
EjectData = new EjectDataBlock();
|
|
}
|
|
|
|
public EjectGroupMemberReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
EjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public EjectGroupMemberReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
EjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
length += EjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
EjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LeaveGroupRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public LeaveGroupRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.LeaveGroupRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 347;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public LeaveGroupRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public LeaveGroupRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LeaveGroupReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public bool Success;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
Success = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Success) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public LeaveGroupReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.LeaveGroupReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 348;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public LeaveGroupReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public LeaveGroupReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InviteGroupRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InviteDataBlock : PacketBlock
|
|
{
|
|
public UUID InviteeID;
|
|
public UUID RoleID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public InviteDataBlock() { }
|
|
public InviteDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
InviteeID.FromBytes(bytes, i); i += 16;
|
|
RoleID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
InviteeID.ToBytes(bytes, i); i += 16;
|
|
RoleID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
for (int j = 0; j < InviteData.Length; j++)
|
|
length += InviteData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
public InviteDataBlock[] InviteData;
|
|
|
|
public InviteGroupRequestPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.InviteGroupRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 349;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
InviteData = null;
|
|
}
|
|
|
|
public InviteGroupRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InviteData == null || InviteData.Length != -1) {
|
|
InviteData = new InviteDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InviteData[j] = new InviteDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InviteData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public InviteGroupRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(InviteData == null || InviteData.Length != count) {
|
|
InviteData = new InviteDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ InviteData[j] = new InviteDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ InviteData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
length++;
|
|
for (int j = 0; j < InviteData.Length; j++) { length += InviteData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)InviteData.Length;
|
|
for (int j = 0; j < InviteData.Length; j++) { InviteData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += GroupData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
GroupData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int InviteDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int InviteDataCount = 0;
|
|
|
|
i = InviteDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < InviteData.Length) {
|
|
int blockLength = InviteData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == InviteDataStart) {
|
|
variableLength += blockLength;
|
|
++InviteDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)InviteDataCount;
|
|
for (i = InviteDataStart; i < InviteDataStart + InviteDataCount; i++) { InviteData[i].ToBytes(packet, ref length); }
|
|
InviteDataStart += InviteDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
InviteDataStart < InviteData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupProfileRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public GroupProfileRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupProfileRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 351;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public GroupProfileRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupProfileRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupProfileReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public byte[] Name;
|
|
public byte[] Charter;
|
|
public bool ShowInList;
|
|
public byte[] MemberTitle;
|
|
public ulong PowersMask;
|
|
public UUID InsigniaID;
|
|
public UUID FounderID;
|
|
public int MembershipFee;
|
|
public bool OpenEnrollment;
|
|
public int Money;
|
|
public int GroupMembershipCount;
|
|
public int GroupRolesCount;
|
|
public bool AllowPublish;
|
|
public bool MaturePublish;
|
|
public UUID OwnerRole;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 96;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Charter != null) { length += Charter.Length; }
|
|
if (MemberTitle != null) { length += MemberTitle.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Charter = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Charter, 0, length); i += length;
|
|
ShowInList = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = bytes[i++];
|
|
MemberTitle = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MemberTitle, 0, length); i += length;
|
|
PowersMask = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
InsigniaID.FromBytes(bytes, i); i += 16;
|
|
FounderID.FromBytes(bytes, i); i += 16;
|
|
MembershipFee = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OpenEnrollment = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Money = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMembershipCount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupRolesCount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
OwnerRole.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)(Charter.Length % 256);
|
|
bytes[i++] = (byte)((Charter.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Charter, 0, bytes, i, Charter.Length); i += Charter.Length;
|
|
bytes[i++] = (byte)((ShowInList) ? 1 : 0);
|
|
bytes[i++] = (byte)MemberTitle.Length;
|
|
Buffer.BlockCopy(MemberTitle, 0, bytes, i, MemberTitle.Length); i += MemberTitle.Length;
|
|
Utils.UInt64ToBytes(PowersMask, bytes, i); i += 8;
|
|
InsigniaID.ToBytes(bytes, i); i += 16;
|
|
FounderID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(MembershipFee, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((OpenEnrollment) ? 1 : 0);
|
|
Utils.IntToBytes(Money, bytes, i); i += 4;
|
|
Utils.IntToBytes(GroupMembershipCount, bytes, i); i += 4;
|
|
Utils.IntToBytes(GroupRolesCount, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((AllowPublish) ? 1 : 0);
|
|
bytes[i++] = (byte)((MaturePublish) ? 1 : 0);
|
|
OwnerRole.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public GroupProfileReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupProfileReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 352;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public GroupProfileReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupProfileReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupAccountSummaryRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public int IntervalDays;
|
|
public int CurrentInterval;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 24;
|
|
}
|
|
}
|
|
|
|
public MoneyDataBlock() { }
|
|
public MoneyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
IntervalDays = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CurrentInterval = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(IntervalDays, bytes, i); i += 4;
|
|
Utils.IntToBytes(CurrentInterval, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MoneyDataBlock MoneyData;
|
|
|
|
public GroupAccountSummaryRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupAccountSummaryRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 353;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MoneyData = new MoneyDataBlock();
|
|
}
|
|
|
|
public GroupAccountSummaryRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupAccountSummaryRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MoneyData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupAccountSummaryReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public int IntervalDays;
|
|
public int CurrentInterval;
|
|
public byte[] StartDate;
|
|
public int Balance;
|
|
public int TotalCredits;
|
|
public int TotalDebits;
|
|
public int ObjectTaxCurrent;
|
|
public int LightTaxCurrent;
|
|
public int LandTaxCurrent;
|
|
public int GroupTaxCurrent;
|
|
public int ParcelDirFeeCurrent;
|
|
public int ObjectTaxEstimate;
|
|
public int LightTaxEstimate;
|
|
public int LandTaxEstimate;
|
|
public int GroupTaxEstimate;
|
|
public int ParcelDirFeeEstimate;
|
|
public int NonExemptMembers;
|
|
public byte[] LastTaxDate;
|
|
public byte[] TaxDate;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 83;
|
|
if (StartDate != null) { length += StartDate.Length; }
|
|
if (LastTaxDate != null) { length += LastTaxDate.Length; }
|
|
if (TaxDate != null) { length += TaxDate.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MoneyDataBlock() { }
|
|
public MoneyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
IntervalDays = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CurrentInterval = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
StartDate = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, StartDate, 0, length); i += length;
|
|
Balance = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TotalCredits = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TotalDebits = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ObjectTaxCurrent = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LightTaxCurrent = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LandTaxCurrent = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupTaxCurrent = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ParcelDirFeeCurrent = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ObjectTaxEstimate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LightTaxEstimate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LandTaxEstimate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupTaxEstimate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ParcelDirFeeEstimate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NonExemptMembers = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
LastTaxDate = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, LastTaxDate, 0, length); i += length;
|
|
length = bytes[i++];
|
|
TaxDate = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TaxDate, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(IntervalDays, bytes, i); i += 4;
|
|
Utils.IntToBytes(CurrentInterval, bytes, i); i += 4;
|
|
bytes[i++] = (byte)StartDate.Length;
|
|
Buffer.BlockCopy(StartDate, 0, bytes, i, StartDate.Length); i += StartDate.Length;
|
|
Utils.IntToBytes(Balance, bytes, i); i += 4;
|
|
Utils.IntToBytes(TotalCredits, bytes, i); i += 4;
|
|
Utils.IntToBytes(TotalDebits, bytes, i); i += 4;
|
|
Utils.IntToBytes(ObjectTaxCurrent, bytes, i); i += 4;
|
|
Utils.IntToBytes(LightTaxCurrent, bytes, i); i += 4;
|
|
Utils.IntToBytes(LandTaxCurrent, bytes, i); i += 4;
|
|
Utils.IntToBytes(GroupTaxCurrent, bytes, i); i += 4;
|
|
Utils.IntToBytes(ParcelDirFeeCurrent, bytes, i); i += 4;
|
|
Utils.IntToBytes(ObjectTaxEstimate, bytes, i); i += 4;
|
|
Utils.IntToBytes(LightTaxEstimate, bytes, i); i += 4;
|
|
Utils.IntToBytes(LandTaxEstimate, bytes, i); i += 4;
|
|
Utils.IntToBytes(GroupTaxEstimate, bytes, i); i += 4;
|
|
Utils.IntToBytes(ParcelDirFeeEstimate, bytes, i); i += 4;
|
|
Utils.IntToBytes(NonExemptMembers, bytes, i); i += 4;
|
|
bytes[i++] = (byte)LastTaxDate.Length;
|
|
Buffer.BlockCopy(LastTaxDate, 0, bytes, i, LastTaxDate.Length); i += LastTaxDate.Length;
|
|
bytes[i++] = (byte)TaxDate.Length;
|
|
Buffer.BlockCopy(TaxDate, 0, bytes, i, TaxDate.Length); i += TaxDate.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MoneyDataBlock MoneyData;
|
|
|
|
public GroupAccountSummaryReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupAccountSummaryReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 354;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MoneyData = new MoneyDataBlock();
|
|
}
|
|
|
|
public GroupAccountSummaryReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupAccountSummaryReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MoneyData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupAccountDetailsRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public int IntervalDays;
|
|
public int CurrentInterval;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 24;
|
|
}
|
|
}
|
|
|
|
public MoneyDataBlock() { }
|
|
public MoneyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
IntervalDays = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CurrentInterval = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(IntervalDays, bytes, i); i += 4;
|
|
Utils.IntToBytes(CurrentInterval, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MoneyDataBlock MoneyData;
|
|
|
|
public GroupAccountDetailsRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupAccountDetailsRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 355;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MoneyData = new MoneyDataBlock();
|
|
}
|
|
|
|
public GroupAccountDetailsRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupAccountDetailsRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MoneyData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupAccountDetailsReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public int IntervalDays;
|
|
public int CurrentInterval;
|
|
public byte[] StartDate;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 25;
|
|
if (StartDate != null) { length += StartDate.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MoneyDataBlock() { }
|
|
public MoneyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
IntervalDays = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CurrentInterval = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
StartDate = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, StartDate, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(IntervalDays, bytes, i); i += 4;
|
|
Utils.IntToBytes(CurrentInterval, bytes, i); i += 4;
|
|
bytes[i++] = (byte)StartDate.Length;
|
|
Buffer.BlockCopy(StartDate, 0, bytes, i, StartDate.Length); i += StartDate.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class HistoryDataBlock : PacketBlock
|
|
{
|
|
public byte[] Description;
|
|
public int Amount;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 5;
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public HistoryDataBlock() { }
|
|
public HistoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
Amount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.IntToBytes(Amount, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
for (int j = 0; j < HistoryData.Length; j++)
|
|
length += HistoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MoneyDataBlock MoneyData;
|
|
public HistoryDataBlock[] HistoryData;
|
|
|
|
public GroupAccountDetailsReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupAccountDetailsReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 356;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MoneyData = new MoneyDataBlock();
|
|
HistoryData = null;
|
|
}
|
|
|
|
public GroupAccountDetailsReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(HistoryData == null || HistoryData.Length != -1) {
|
|
HistoryData = new HistoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ HistoryData[j] = new HistoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ HistoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupAccountDetailsReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(HistoryData == null || HistoryData.Length != count) {
|
|
HistoryData = new HistoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ HistoryData[j] = new HistoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ HistoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
length++;
|
|
for (int j = 0; j < HistoryData.Length; j++) { length += HistoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MoneyData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)HistoryData.Length;
|
|
for (int j = 0; j < HistoryData.Length; j++) { HistoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += MoneyData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
MoneyData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int HistoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int HistoryDataCount = 0;
|
|
|
|
i = HistoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < HistoryData.Length) {
|
|
int blockLength = HistoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == HistoryDataStart) {
|
|
variableLength += blockLength;
|
|
++HistoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)HistoryDataCount;
|
|
for (i = HistoryDataStart; i < HistoryDataStart + HistoryDataCount; i++) { HistoryData[i].ToBytes(packet, ref length); }
|
|
HistoryDataStart += HistoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
HistoryDataStart < HistoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupAccountTransactionsRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public int IntervalDays;
|
|
public int CurrentInterval;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 24;
|
|
}
|
|
}
|
|
|
|
public MoneyDataBlock() { }
|
|
public MoneyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
IntervalDays = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CurrentInterval = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(IntervalDays, bytes, i); i += 4;
|
|
Utils.IntToBytes(CurrentInterval, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MoneyDataBlock MoneyData;
|
|
|
|
public GroupAccountTransactionsRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupAccountTransactionsRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 357;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MoneyData = new MoneyDataBlock();
|
|
}
|
|
|
|
public GroupAccountTransactionsRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupAccountTransactionsRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MoneyData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupAccountTransactionsReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public int IntervalDays;
|
|
public int CurrentInterval;
|
|
public byte[] StartDate;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 25;
|
|
if (StartDate != null) { length += StartDate.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MoneyDataBlock() { }
|
|
public MoneyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
IntervalDays = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CurrentInterval = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
StartDate = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, StartDate, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(IntervalDays, bytes, i); i += 4;
|
|
Utils.IntToBytes(CurrentInterval, bytes, i); i += 4;
|
|
bytes[i++] = (byte)StartDate.Length;
|
|
Buffer.BlockCopy(StartDate, 0, bytes, i, StartDate.Length); i += StartDate.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class HistoryDataBlock : PacketBlock
|
|
{
|
|
public byte[] Time;
|
|
public byte[] User;
|
|
public int Type;
|
|
public byte[] Item;
|
|
public int Amount;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
if (Time != null) { length += Time.Length; }
|
|
if (User != null) { length += User.Length; }
|
|
if (Item != null) { length += Item.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public HistoryDataBlock() { }
|
|
public HistoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Time = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Time, 0, length); i += length;
|
|
length = bytes[i++];
|
|
User = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, User, 0, length); i += length;
|
|
Type = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Item = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Item, 0, length); i += length;
|
|
Amount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Time.Length;
|
|
Buffer.BlockCopy(Time, 0, bytes, i, Time.Length); i += Time.Length;
|
|
bytes[i++] = (byte)User.Length;
|
|
Buffer.BlockCopy(User, 0, bytes, i, User.Length); i += User.Length;
|
|
Utils.IntToBytes(Type, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Item.Length;
|
|
Buffer.BlockCopy(Item, 0, bytes, i, Item.Length); i += Item.Length;
|
|
Utils.IntToBytes(Amount, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
for (int j = 0; j < HistoryData.Length; j++)
|
|
length += HistoryData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MoneyDataBlock MoneyData;
|
|
public HistoryDataBlock[] HistoryData;
|
|
|
|
public GroupAccountTransactionsReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupAccountTransactionsReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 358;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
MoneyData = new MoneyDataBlock();
|
|
HistoryData = null;
|
|
}
|
|
|
|
public GroupAccountTransactionsReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(HistoryData == null || HistoryData.Length != -1) {
|
|
HistoryData = new HistoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ HistoryData[j] = new HistoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ HistoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupAccountTransactionsReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MoneyData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(HistoryData == null || HistoryData.Length != count) {
|
|
HistoryData = new HistoryDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ HistoryData[j] = new HistoryDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ HistoryData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MoneyData.Length;
|
|
length++;
|
|
for (int j = 0; j < HistoryData.Length; j++) { length += HistoryData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MoneyData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)HistoryData.Length;
|
|
for (int j = 0; j < HistoryData.Length; j++) { HistoryData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += MoneyData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
MoneyData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int HistoryDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int HistoryDataCount = 0;
|
|
|
|
i = HistoryDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < HistoryData.Length) {
|
|
int blockLength = HistoryData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == HistoryDataStart) {
|
|
variableLength += blockLength;
|
|
++HistoryDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)HistoryDataCount;
|
|
for (i = HistoryDataStart; i < HistoryDataStart + HistoryDataCount; i++) { HistoryData[i].ToBytes(packet, ref length); }
|
|
HistoryDataStart += HistoryDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
HistoryDataStart < HistoryData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupActiveProposalsRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionDataBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TransactionDataBlock() { }
|
|
public TransactionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
length += TransactionData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
public TransactionDataBlock TransactionData;
|
|
|
|
public GroupActiveProposalsRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupActiveProposalsRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 359;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
TransactionData = new TransactionDataBlock();
|
|
}
|
|
|
|
public GroupActiveProposalsRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupActiveProposalsRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
length += TransactionData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
TransactionData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupActiveProposalItemReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionDataBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
public uint TotalNumItems;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public TransactionDataBlock() { }
|
|
public TransactionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
TotalNumItems = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(TotalNumItems, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ProposalDataBlock : PacketBlock
|
|
{
|
|
public UUID VoteID;
|
|
public UUID VoteInitiator;
|
|
public byte[] TerseDateID;
|
|
public byte[] StartDateTime;
|
|
public byte[] EndDateTime;
|
|
public bool AlreadyVoted;
|
|
public byte[] VoteCast;
|
|
public float Majority;
|
|
public int Quorum;
|
|
public byte[] ProposalText;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 46;
|
|
if (TerseDateID != null) { length += TerseDateID.Length; }
|
|
if (StartDateTime != null) { length += StartDateTime.Length; }
|
|
if (EndDateTime != null) { length += EndDateTime.Length; }
|
|
if (VoteCast != null) { length += VoteCast.Length; }
|
|
if (ProposalText != null) { length += ProposalText.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ProposalDataBlock() { }
|
|
public ProposalDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
VoteID.FromBytes(bytes, i); i += 16;
|
|
VoteInitiator.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
TerseDateID = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TerseDateID, 0, length); i += length;
|
|
length = bytes[i++];
|
|
StartDateTime = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, StartDateTime, 0, length); i += length;
|
|
length = bytes[i++];
|
|
EndDateTime = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, EndDateTime, 0, length); i += length;
|
|
AlreadyVoted = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = bytes[i++];
|
|
VoteCast = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, VoteCast, 0, length); i += length;
|
|
Majority = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Quorum = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
ProposalText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ProposalText, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
VoteID.ToBytes(bytes, i); i += 16;
|
|
VoteInitiator.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)TerseDateID.Length;
|
|
Buffer.BlockCopy(TerseDateID, 0, bytes, i, TerseDateID.Length); i += TerseDateID.Length;
|
|
bytes[i++] = (byte)StartDateTime.Length;
|
|
Buffer.BlockCopy(StartDateTime, 0, bytes, i, StartDateTime.Length); i += StartDateTime.Length;
|
|
bytes[i++] = (byte)EndDateTime.Length;
|
|
Buffer.BlockCopy(EndDateTime, 0, bytes, i, EndDateTime.Length); i += EndDateTime.Length;
|
|
bytes[i++] = (byte)((AlreadyVoted) ? 1 : 0);
|
|
bytes[i++] = (byte)VoteCast.Length;
|
|
Buffer.BlockCopy(VoteCast, 0, bytes, i, VoteCast.Length); i += VoteCast.Length;
|
|
Utils.FloatToBytes(Majority, bytes, i); i += 4;
|
|
Utils.IntToBytes(Quorum, bytes, i); i += 4;
|
|
bytes[i++] = (byte)ProposalText.Length;
|
|
Buffer.BlockCopy(ProposalText, 0, bytes, i, ProposalText.Length); i += ProposalText.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += TransactionData.Length;
|
|
for (int j = 0; j < ProposalData.Length; j++)
|
|
length += ProposalData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public TransactionDataBlock TransactionData;
|
|
public ProposalDataBlock[] ProposalData;
|
|
|
|
public GroupActiveProposalItemReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupActiveProposalItemReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 360;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
TransactionData = new TransactionDataBlock();
|
|
ProposalData = null;
|
|
}
|
|
|
|
public GroupActiveProposalItemReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ProposalData == null || ProposalData.Length != -1) {
|
|
ProposalData = new ProposalDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ProposalData[j] = new ProposalDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ProposalData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupActiveProposalItemReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ProposalData == null || ProposalData.Length != count) {
|
|
ProposalData = new ProposalDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ProposalData[j] = new ProposalDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ProposalData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionData.Length;
|
|
length++;
|
|
for (int j = 0; j < ProposalData.Length; j++) { length += ProposalData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TransactionData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ProposalData.Length;
|
|
for (int j = 0; j < ProposalData.Length; j++) { ProposalData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += TransactionData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
TransactionData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ProposalDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ProposalDataCount = 0;
|
|
|
|
i = ProposalDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ProposalData.Length) {
|
|
int blockLength = ProposalData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ProposalDataStart) {
|
|
variableLength += blockLength;
|
|
++ProposalDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ProposalDataCount;
|
|
for (i = ProposalDataStart; i < ProposalDataStart + ProposalDataCount; i++) { ProposalData[i].ToBytes(packet, ref length); }
|
|
ProposalDataStart += ProposalDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ProposalDataStart < ProposalData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupVoteHistoryRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionDataBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public TransactionDataBlock() { }
|
|
public TransactionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
length += TransactionData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
public TransactionDataBlock TransactionData;
|
|
|
|
public GroupVoteHistoryRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupVoteHistoryRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 361;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
TransactionData = new TransactionDataBlock();
|
|
}
|
|
|
|
public GroupVoteHistoryRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupVoteHistoryRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
length += TransactionData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
TransactionData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupVoteHistoryItemReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransactionDataBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
public uint TotalNumItems;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public TransactionDataBlock() { }
|
|
public TransactionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
TotalNumItems = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(TotalNumItems, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class HistoryItemDataBlock : PacketBlock
|
|
{
|
|
public UUID VoteID;
|
|
public byte[] TerseDateID;
|
|
public byte[] StartDateTime;
|
|
public byte[] EndDateTime;
|
|
public UUID VoteInitiator;
|
|
public byte[] VoteType;
|
|
public byte[] VoteResult;
|
|
public float Majority;
|
|
public int Quorum;
|
|
public byte[] ProposalText;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 47;
|
|
if (TerseDateID != null) { length += TerseDateID.Length; }
|
|
if (StartDateTime != null) { length += StartDateTime.Length; }
|
|
if (EndDateTime != null) { length += EndDateTime.Length; }
|
|
if (VoteType != null) { length += VoteType.Length; }
|
|
if (VoteResult != null) { length += VoteResult.Length; }
|
|
if (ProposalText != null) { length += ProposalText.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public HistoryItemDataBlock() { }
|
|
public HistoryItemDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
VoteID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
TerseDateID = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TerseDateID, 0, length); i += length;
|
|
length = bytes[i++];
|
|
StartDateTime = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, StartDateTime, 0, length); i += length;
|
|
length = bytes[i++];
|
|
EndDateTime = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, EndDateTime, 0, length); i += length;
|
|
VoteInitiator.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
VoteType = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, VoteType, 0, length); i += length;
|
|
length = bytes[i++];
|
|
VoteResult = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, VoteResult, 0, length); i += length;
|
|
Majority = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Quorum = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
ProposalText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ProposalText, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
VoteID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)TerseDateID.Length;
|
|
Buffer.BlockCopy(TerseDateID, 0, bytes, i, TerseDateID.Length); i += TerseDateID.Length;
|
|
bytes[i++] = (byte)StartDateTime.Length;
|
|
Buffer.BlockCopy(StartDateTime, 0, bytes, i, StartDateTime.Length); i += StartDateTime.Length;
|
|
bytes[i++] = (byte)EndDateTime.Length;
|
|
Buffer.BlockCopy(EndDateTime, 0, bytes, i, EndDateTime.Length); i += EndDateTime.Length;
|
|
VoteInitiator.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)VoteType.Length;
|
|
Buffer.BlockCopy(VoteType, 0, bytes, i, VoteType.Length); i += VoteType.Length;
|
|
bytes[i++] = (byte)VoteResult.Length;
|
|
Buffer.BlockCopy(VoteResult, 0, bytes, i, VoteResult.Length); i += VoteResult.Length;
|
|
Utils.FloatToBytes(Majority, bytes, i); i += 4;
|
|
Utils.IntToBytes(Quorum, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(ProposalText.Length % 256);
|
|
bytes[i++] = (byte)((ProposalText.Length >> 8) % 256);
|
|
Buffer.BlockCopy(ProposalText, 0, bytes, i, ProposalText.Length); i += ProposalText.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class VoteItemBlock : PacketBlock
|
|
{
|
|
public UUID CandidateID;
|
|
public byte[] VoteCast;
|
|
public int NumVotes;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 21;
|
|
if (VoteCast != null) { length += VoteCast.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public VoteItemBlock() { }
|
|
public VoteItemBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
CandidateID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
VoteCast = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, VoteCast, 0, length); i += length;
|
|
NumVotes = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
CandidateID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)VoteCast.Length;
|
|
Buffer.BlockCopy(VoteCast, 0, bytes, i, VoteCast.Length); i += VoteCast.Length;
|
|
Utils.IntToBytes(NumVotes, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += TransactionData.Length;
|
|
length += HistoryItemData.Length;
|
|
for (int j = 0; j < VoteItem.Length; j++)
|
|
length += VoteItem[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public TransactionDataBlock TransactionData;
|
|
public HistoryItemDataBlock HistoryItemData;
|
|
public VoteItemBlock[] VoteItem;
|
|
|
|
public GroupVoteHistoryItemReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupVoteHistoryItemReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 362;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
TransactionData = new TransactionDataBlock();
|
|
HistoryItemData = new HistoryItemDataBlock();
|
|
VoteItem = null;
|
|
}
|
|
|
|
public GroupVoteHistoryItemReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
HistoryItemData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(VoteItem == null || VoteItem.Length != -1) {
|
|
VoteItem = new VoteItemBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ VoteItem[j] = new VoteItemBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ VoteItem[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupVoteHistoryItemReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TransactionData.FromBytes(bytes, ref i);
|
|
HistoryItemData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(VoteItem == null || VoteItem.Length != count) {
|
|
VoteItem = new VoteItemBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ VoteItem[j] = new VoteItemBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ VoteItem[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += TransactionData.Length;
|
|
length += HistoryItemData.Length;
|
|
length++;
|
|
for (int j = 0; j < VoteItem.Length; j++) { length += VoteItem[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TransactionData.ToBytes(bytes, ref i);
|
|
HistoryItemData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)VoteItem.Length;
|
|
for (int j = 0; j < VoteItem.Length; j++) { VoteItem[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += TransactionData.Length;
|
|
fixedLength += HistoryItemData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
TransactionData.ToBytes(fixedBytes, ref i);
|
|
HistoryItemData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int VoteItemStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int VoteItemCount = 0;
|
|
|
|
i = VoteItemStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < VoteItem.Length) {
|
|
int blockLength = VoteItem[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == VoteItemStart) {
|
|
variableLength += blockLength;
|
|
++VoteItemCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)VoteItemCount;
|
|
for (i = VoteItemStart; i < VoteItemStart + VoteItemCount; i++) { VoteItem[i].ToBytes(packet, ref length); }
|
|
VoteItemStart += VoteItemCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
VoteItemStart < VoteItem.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StartGroupProposalPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ProposalDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public int Quorum;
|
|
public float Majority;
|
|
public int Duration;
|
|
public byte[] ProposalText;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 29;
|
|
if (ProposalText != null) { length += ProposalText.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ProposalDataBlock() { }
|
|
public ProposalDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
Quorum = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Majority = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Duration = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
ProposalText = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ProposalText, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(Quorum, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Majority, bytes, i); i += 4;
|
|
Utils.IntToBytes(Duration, bytes, i); i += 4;
|
|
bytes[i++] = (byte)ProposalText.Length;
|
|
Buffer.BlockCopy(ProposalText, 0, bytes, i, ProposalText.Length); i += ProposalText.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ProposalData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ProposalDataBlock ProposalData;
|
|
|
|
public StartGroupProposalPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.StartGroupProposal;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 363;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ProposalData = new ProposalDataBlock();
|
|
}
|
|
|
|
public StartGroupProposalPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ProposalData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public StartGroupProposalPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ProposalData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ProposalData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ProposalData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupProposalBallotPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ProposalDataBlock : PacketBlock
|
|
{
|
|
public UUID ProposalID;
|
|
public UUID GroupID;
|
|
public byte[] VoteCast;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 33;
|
|
if (VoteCast != null) { length += VoteCast.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ProposalDataBlock() { }
|
|
public ProposalDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ProposalID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
VoteCast = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, VoteCast, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ProposalID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)VoteCast.Length;
|
|
Buffer.BlockCopy(VoteCast, 0, bytes, i, VoteCast.Length); i += VoteCast.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ProposalData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ProposalDataBlock ProposalData;
|
|
|
|
public GroupProposalBallotPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupProposalBallot;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 364;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ProposalData = new ProposalDataBlock();
|
|
}
|
|
|
|
public GroupProposalBallotPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ProposalData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupProposalBallotPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ProposalData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ProposalData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ProposalData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupMembersRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public UUID RequestID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public GroupMembersRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupMembersRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 366;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public GroupMembersRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupMembersRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupMembersReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public UUID RequestID;
|
|
public int MemberCount;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
MemberCount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(MemberCount, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MemberDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public int Contribution;
|
|
public byte[] OnlineStatus;
|
|
public ulong AgentPowers;
|
|
public byte[] Title;
|
|
public bool IsOwner;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 31;
|
|
if (OnlineStatus != null) { length += OnlineStatus.Length; }
|
|
if (Title != null) { length += Title.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MemberDataBlock() { }
|
|
public MemberDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
Contribution = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
OnlineStatus = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, OnlineStatus, 0, length); i += length;
|
|
AgentPowers = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
length = bytes[i++];
|
|
Title = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Title, 0, length); i += length;
|
|
IsOwner = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(Contribution, bytes, i); i += 4;
|
|
bytes[i++] = (byte)OnlineStatus.Length;
|
|
Buffer.BlockCopy(OnlineStatus, 0, bytes, i, OnlineStatus.Length); i += OnlineStatus.Length;
|
|
Utils.UInt64ToBytes(AgentPowers, bytes, i); i += 8;
|
|
bytes[i++] = (byte)Title.Length;
|
|
Buffer.BlockCopy(Title, 0, bytes, i, Title.Length); i += Title.Length;
|
|
bytes[i++] = (byte)((IsOwner) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
for (int j = 0; j < MemberData.Length; j++)
|
|
length += MemberData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
public MemberDataBlock[] MemberData;
|
|
|
|
public GroupMembersReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupMembersReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 367;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
MemberData = null;
|
|
}
|
|
|
|
public GroupMembersReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(MemberData == null || MemberData.Length != -1) {
|
|
MemberData = new MemberDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ MemberData[j] = new MemberDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ MemberData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupMembersReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(MemberData == null || MemberData.Length != count) {
|
|
MemberData = new MemberDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ MemberData[j] = new MemberDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ MemberData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
length++;
|
|
for (int j = 0; j < MemberData.Length; j++) { length += MemberData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)MemberData.Length;
|
|
for (int j = 0; j < MemberData.Length; j++) { MemberData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += GroupData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
GroupData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int MemberDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int MemberDataCount = 0;
|
|
|
|
i = MemberDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < MemberData.Length) {
|
|
int blockLength = MemberData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == MemberDataStart) {
|
|
variableLength += blockLength;
|
|
++MemberDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)MemberDataCount;
|
|
for (i = MemberDataStart; i < MemberDataStart + MemberDataCount; i++) { MemberData[i].ToBytes(packet, ref length); }
|
|
MemberDataStart += MemberDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
MemberDataStart < MemberData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ActivateGroupPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public ActivateGroupPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ActivateGroup;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 368;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public ActivateGroupPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ActivateGroupPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SetGroupContributionPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public int Contribution;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
Contribution = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(Contribution, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public SetGroupContributionPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SetGroupContribution;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 369;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public SetGroupContributionPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SetGroupContributionPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SetGroupAcceptNoticesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public bool AcceptNotices;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
AcceptNotices = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((AcceptNotices) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class NewDataBlock : PacketBlock
|
|
{
|
|
public bool ListInProfile;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public NewDataBlock() { }
|
|
public NewDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ListInProfile = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((ListInProfile) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
length += NewData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
public NewDataBlock NewData;
|
|
|
|
public SetGroupAcceptNoticesPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SetGroupAcceptNotices;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 370;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
NewData = new NewDataBlock();
|
|
}
|
|
|
|
public SetGroupAcceptNoticesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
NewData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SetGroupAcceptNoticesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
NewData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
length += NewData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
NewData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupRoleDataRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public UUID RequestID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public GroupRoleDataRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupRoleDataRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 371;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public GroupRoleDataRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupRoleDataRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupRoleDataReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public UUID RequestID;
|
|
public int RoleCount;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
RoleCount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(RoleCount, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RoleDataBlock : PacketBlock
|
|
{
|
|
public UUID RoleID;
|
|
public byte[] Name;
|
|
public byte[] Title;
|
|
public byte[] Description;
|
|
public ulong Powers;
|
|
public uint Members;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 31;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Title != null) { length += Title.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RoleDataBlock() { }
|
|
public RoleDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
RoleID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Title = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Title, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
Powers = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
Members = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RoleID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Title.Length;
|
|
Buffer.BlockCopy(Title, 0, bytes, i, Title.Length); i += Title.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.UInt64ToBytes(Powers, bytes, i); i += 8;
|
|
Utils.UIntToBytes(Members, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
for (int j = 0; j < RoleData.Length; j++)
|
|
length += RoleData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
public RoleDataBlock[] RoleData;
|
|
|
|
public GroupRoleDataReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupRoleDataReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 372;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
RoleData = null;
|
|
}
|
|
|
|
public GroupRoleDataReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RoleData == null || RoleData.Length != -1) {
|
|
RoleData = new RoleDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RoleData[j] = new RoleDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RoleData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupRoleDataReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RoleData == null || RoleData.Length != count) {
|
|
RoleData = new RoleDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RoleData[j] = new RoleDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RoleData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
length++;
|
|
for (int j = 0; j < RoleData.Length; j++) { length += RoleData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)RoleData.Length;
|
|
for (int j = 0; j < RoleData.Length; j++) { RoleData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += GroupData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
GroupData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int RoleDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int RoleDataCount = 0;
|
|
|
|
i = RoleDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < RoleData.Length) {
|
|
int blockLength = RoleData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == RoleDataStart) {
|
|
variableLength += blockLength;
|
|
++RoleDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)RoleDataCount;
|
|
for (i = RoleDataStart; i < RoleDataStart + RoleDataCount; i++) { RoleData[i].ToBytes(packet, ref length); }
|
|
RoleDataStart += RoleDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
RoleDataStart < RoleData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupRoleMembersRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public UUID RequestID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public GroupRoleMembersRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupRoleMembersRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 373;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public GroupRoleMembersRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupRoleMembersRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupRoleMembersReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
public UUID RequestID;
|
|
public uint TotalPairs;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 52;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
TotalPairs = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(TotalPairs, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MemberDataBlock : PacketBlock
|
|
{
|
|
public UUID RoleID;
|
|
public UUID MemberID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public MemberDataBlock() { }
|
|
public MemberDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RoleID.FromBytes(bytes, i); i += 16;
|
|
MemberID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RoleID.ToBytes(bytes, i); i += 16;
|
|
MemberID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < MemberData.Length; j++)
|
|
length += MemberData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MemberDataBlock[] MemberData;
|
|
|
|
public GroupRoleMembersReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupRoleMembersReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 374;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
MemberData = null;
|
|
}
|
|
|
|
public GroupRoleMembersReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(MemberData == null || MemberData.Length != -1) {
|
|
MemberData = new MemberDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ MemberData[j] = new MemberDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ MemberData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupRoleMembersReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(MemberData == null || MemberData.Length != count) {
|
|
MemberData = new MemberDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ MemberData[j] = new MemberDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ MemberData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < MemberData.Length; j++) { length += MemberData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)MemberData.Length;
|
|
for (int j = 0; j < MemberData.Length; j++) { MemberData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int MemberDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int MemberDataCount = 0;
|
|
|
|
i = MemberDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < MemberData.Length) {
|
|
int blockLength = MemberData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == MemberDataStart) {
|
|
variableLength += blockLength;
|
|
++MemberDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)MemberDataCount;
|
|
for (i = MemberDataStart; i < MemberDataStart + MemberDataCount; i++) { MemberData[i].ToBytes(packet, ref length); }
|
|
MemberDataStart += MemberDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
MemberDataStart < MemberData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupTitlesRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
public UUID RequestID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 64;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public GroupTitlesRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupTitlesRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 375;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public GroupTitlesRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupTitlesRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupTitlesReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
public UUID RequestID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public byte[] Title;
|
|
public UUID RoleID;
|
|
public bool Selected;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 18;
|
|
if (Title != null) { length += Title.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Title = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Title, 0, length); i += length;
|
|
RoleID.FromBytes(bytes, i); i += 16;
|
|
Selected = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Title.Length;
|
|
Buffer.BlockCopy(Title, 0, bytes, i, Title.Length); i += Title.Length;
|
|
RoleID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((Selected) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < GroupData.Length; j++)
|
|
length += GroupData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock[] GroupData;
|
|
|
|
public GroupTitlesReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupTitlesReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 376;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = null;
|
|
}
|
|
|
|
public GroupTitlesReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(GroupData == null || GroupData.Length != -1) {
|
|
GroupData = new GroupDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ GroupData[j] = new GroupDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ GroupData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupTitlesReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(GroupData == null || GroupData.Length != count) {
|
|
GroupData = new GroupDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ GroupData[j] = new GroupDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ GroupData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < GroupData.Length; j++) { length += GroupData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)GroupData.Length;
|
|
for (int j = 0; j < GroupData.Length; j++) { GroupData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int GroupDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int GroupDataCount = 0;
|
|
|
|
i = GroupDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < GroupData.Length) {
|
|
int blockLength = GroupData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == GroupDataStart) {
|
|
variableLength += blockLength;
|
|
++GroupDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)GroupDataCount;
|
|
for (i = GroupDataStart; i < GroupDataStart + GroupDataCount; i++) { GroupData[i].ToBytes(packet, ref length); }
|
|
GroupDataStart += GroupDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
GroupDataStart < GroupData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupTitleUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
public UUID TitleRoleID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 64;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
TitleRoleID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
TitleRoleID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public GroupTitleUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GroupTitleUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 377;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public GroupTitleUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GroupTitleUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupRoleUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RoleDataBlock : PacketBlock
|
|
{
|
|
public UUID RoleID;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public byte[] Title;
|
|
public ulong Powers;
|
|
public byte UpdateType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 28;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
if (Title != null) { length += Title.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RoleDataBlock() { }
|
|
public RoleDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
RoleID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Title = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Title, 0, length); i += length;
|
|
Powers = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
UpdateType = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RoleID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
bytes[i++] = (byte)Title.Length;
|
|
Buffer.BlockCopy(Title, 0, bytes, i, Title.Length); i += Title.Length;
|
|
Utils.UInt64ToBytes(Powers, bytes, i); i += 8;
|
|
bytes[i++] = UpdateType;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < RoleData.Length; j++)
|
|
length += RoleData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RoleDataBlock[] RoleData;
|
|
|
|
public GroupRoleUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupRoleUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 378;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
RoleData = null;
|
|
}
|
|
|
|
public GroupRoleUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RoleData == null || RoleData.Length != -1) {
|
|
RoleData = new RoleDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RoleData[j] = new RoleDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RoleData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupRoleUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RoleData == null || RoleData.Length != count) {
|
|
RoleData = new RoleDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RoleData[j] = new RoleDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RoleData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < RoleData.Length; j++) { length += RoleData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)RoleData.Length;
|
|
for (int j = 0; j < RoleData.Length; j++) { RoleData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int RoleDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int RoleDataCount = 0;
|
|
|
|
i = RoleDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < RoleData.Length) {
|
|
int blockLength = RoleData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == RoleDataStart) {
|
|
variableLength += blockLength;
|
|
++RoleDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)RoleDataCount;
|
|
for (i = RoleDataStart; i < RoleDataStart + RoleDataCount; i++) { RoleData[i].ToBytes(packet, ref length); }
|
|
RoleDataStart += RoleDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
RoleDataStart < RoleData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LiveHelpGroupRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class RequestDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public RequestDataBlock() { }
|
|
public RequestDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += RequestData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RequestDataBlock RequestData;
|
|
|
|
public LiveHelpGroupRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.LiveHelpGroupRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 379;
|
|
Header.Reliable = true;
|
|
RequestData = new RequestDataBlock();
|
|
}
|
|
|
|
public LiveHelpGroupRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
RequestData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public LiveHelpGroupRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
RequestData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += RequestData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RequestData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LiveHelpGroupReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ReplyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public UUID GroupID;
|
|
public byte[] Selection;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 33;
|
|
if (Selection != null) { length += Selection.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ReplyDataBlock() { }
|
|
public ReplyDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
RequestID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Selection = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Selection, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
RequestID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Selection.Length;
|
|
Buffer.BlockCopy(Selection, 0, bytes, i, Selection.Length); i += Selection.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += ReplyData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ReplyDataBlock ReplyData;
|
|
|
|
public LiveHelpGroupReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.LiveHelpGroupReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 380;
|
|
Header.Reliable = true;
|
|
ReplyData = new ReplyDataBlock();
|
|
}
|
|
|
|
public LiveHelpGroupReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ReplyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public LiveHelpGroupReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ReplyData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += ReplyData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ReplyData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentWearablesRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public AgentWearablesRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentWearablesRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 381;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public AgentWearablesRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentWearablesRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentWearablesUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint SerialNum;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
SerialNum = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(SerialNum, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class WearableDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID AssetID;
|
|
public byte WearableType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public WearableDataBlock() { }
|
|
public WearableDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
AssetID.FromBytes(bytes, i); i += 16;
|
|
WearableType = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
AssetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = WearableType;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < WearableData.Length; j++)
|
|
length += WearableData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public WearableDataBlock[] WearableData;
|
|
|
|
public AgentWearablesUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AgentWearablesUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 382;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
WearableData = null;
|
|
}
|
|
|
|
public AgentWearablesUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(WearableData == null || WearableData.Length != -1) {
|
|
WearableData = new WearableDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ WearableData[j] = new WearableDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ WearableData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AgentWearablesUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(WearableData == null || WearableData.Length != count) {
|
|
WearableData = new WearableDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ WearableData[j] = new WearableDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ WearableData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < WearableData.Length; j++) { length += WearableData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)WearableData.Length;
|
|
for (int j = 0; j < WearableData.Length; j++) { WearableData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int WearableDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int WearableDataCount = 0;
|
|
|
|
i = WearableDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < WearableData.Length) {
|
|
int blockLength = WearableData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == WearableDataStart) {
|
|
variableLength += blockLength;
|
|
++WearableDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)WearableDataCount;
|
|
for (i = WearableDataStart; i < WearableDataStart + WearableDataCount; i++) { WearableData[i].ToBytes(packet, ref length); }
|
|
WearableDataStart += WearableDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
WearableDataStart < WearableData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentIsNowWearingPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class WearableDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public byte WearableType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public WearableDataBlock() { }
|
|
public WearableDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
WearableType = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = WearableType;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < WearableData.Length; j++)
|
|
length += WearableData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public WearableDataBlock[] WearableData;
|
|
|
|
public AgentIsNowWearingPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AgentIsNowWearing;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 383;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
WearableData = null;
|
|
}
|
|
|
|
public AgentIsNowWearingPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(WearableData == null || WearableData.Length != -1) {
|
|
WearableData = new WearableDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ WearableData[j] = new WearableDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ WearableData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AgentIsNowWearingPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(WearableData == null || WearableData.Length != count) {
|
|
WearableData = new WearableDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ WearableData[j] = new WearableDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ WearableData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < WearableData.Length; j++) { length += WearableData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)WearableData.Length;
|
|
for (int j = 0; j < WearableData.Length; j++) { WearableData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int WearableDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int WearableDataCount = 0;
|
|
|
|
i = WearableDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < WearableData.Length) {
|
|
int blockLength = WearableData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == WearableDataStart) {
|
|
variableLength += blockLength;
|
|
++WearableDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)WearableDataCount;
|
|
for (i = WearableDataStart; i < WearableDataStart + WearableDataCount; i++) { WearableData[i].ToBytes(packet, ref length); }
|
|
WearableDataStart += WearableDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
WearableDataStart < WearableData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentCachedTexturePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public int SerialNum;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
SerialNum = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(SerialNum, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class WearableDataBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public byte TextureIndex;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public WearableDataBlock() { }
|
|
public WearableDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
TextureIndex = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = TextureIndex;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < WearableData.Length; j++)
|
|
length += WearableData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public WearableDataBlock[] WearableData;
|
|
|
|
public AgentCachedTexturePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AgentCachedTexture;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 384;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
WearableData = null;
|
|
}
|
|
|
|
public AgentCachedTexturePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(WearableData == null || WearableData.Length != -1) {
|
|
WearableData = new WearableDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ WearableData[j] = new WearableDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ WearableData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AgentCachedTexturePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(WearableData == null || WearableData.Length != count) {
|
|
WearableData = new WearableDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ WearableData[j] = new WearableDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ WearableData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < WearableData.Length; j++) { length += WearableData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)WearableData.Length;
|
|
for (int j = 0; j < WearableData.Length; j++) { WearableData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int WearableDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int WearableDataCount = 0;
|
|
|
|
i = WearableDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < WearableData.Length) {
|
|
int blockLength = WearableData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == WearableDataStart) {
|
|
variableLength += blockLength;
|
|
++WearableDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)WearableDataCount;
|
|
for (i = WearableDataStart; i < WearableDataStart + WearableDataCount; i++) { WearableData[i].ToBytes(packet, ref length); }
|
|
WearableDataStart += WearableDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
WearableDataStart < WearableData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentCachedTextureResponsePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public int SerialNum;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
SerialNum = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(SerialNum, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class WearableDataBlock : PacketBlock
|
|
{
|
|
public UUID TextureID;
|
|
public byte TextureIndex;
|
|
public byte[] HostName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 18;
|
|
if (HostName != null) { length += HostName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public WearableDataBlock() { }
|
|
public WearableDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TextureID.FromBytes(bytes, i); i += 16;
|
|
TextureIndex = (byte)bytes[i++];
|
|
length = bytes[i++];
|
|
HostName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, HostName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TextureID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = TextureIndex;
|
|
bytes[i++] = (byte)HostName.Length;
|
|
Buffer.BlockCopy(HostName, 0, bytes, i, HostName.Length); i += HostName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < WearableData.Length; j++)
|
|
length += WearableData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public WearableDataBlock[] WearableData;
|
|
|
|
public AgentCachedTextureResponsePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AgentCachedTextureResponse;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 385;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
WearableData = null;
|
|
}
|
|
|
|
public AgentCachedTextureResponsePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(WearableData == null || WearableData.Length != -1) {
|
|
WearableData = new WearableDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ WearableData[j] = new WearableDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ WearableData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AgentCachedTextureResponsePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(WearableData == null || WearableData.Length != count) {
|
|
WearableData = new WearableDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ WearableData[j] = new WearableDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ WearableData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < WearableData.Length; j++) { length += WearableData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)WearableData.Length;
|
|
for (int j = 0; j < WearableData.Length; j++) { WearableData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int WearableDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int WearableDataCount = 0;
|
|
|
|
i = WearableDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < WearableData.Length) {
|
|
int blockLength = WearableData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == WearableDataStart) {
|
|
variableLength += blockLength;
|
|
++WearableDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)WearableDataCount;
|
|
for (i = WearableDataStart; i < WearableDataStart + WearableDataCount; i++) { WearableData[i].ToBytes(packet, ref length); }
|
|
WearableDataStart += WearableDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
WearableDataStart < WearableData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataUpdateRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public AgentDataUpdateRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentDataUpdateRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 386;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public AgentDataUpdateRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentDataUpdateRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public byte[] FirstName;
|
|
public byte[] LastName;
|
|
public byte[] GroupTitle;
|
|
public UUID ActiveGroupID;
|
|
public ulong GroupPowers;
|
|
public byte[] GroupName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 44;
|
|
if (FirstName != null) { length += FirstName.Length; }
|
|
if (LastName != null) { length += LastName.Length; }
|
|
if (GroupTitle != null) { length += GroupTitle.Length; }
|
|
if (GroupName != null) { length += GroupName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
FirstName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, FirstName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
LastName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, LastName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
GroupTitle = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, GroupTitle, 0, length); i += length;
|
|
ActiveGroupID.FromBytes(bytes, i); i += 16;
|
|
GroupPowers = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
length = bytes[i++];
|
|
GroupName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, GroupName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)FirstName.Length;
|
|
Buffer.BlockCopy(FirstName, 0, bytes, i, FirstName.Length); i += FirstName.Length;
|
|
bytes[i++] = (byte)LastName.Length;
|
|
Buffer.BlockCopy(LastName, 0, bytes, i, LastName.Length); i += LastName.Length;
|
|
bytes[i++] = (byte)GroupTitle.Length;
|
|
Buffer.BlockCopy(GroupTitle, 0, bytes, i, GroupTitle.Length); i += GroupTitle.Length;
|
|
ActiveGroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UInt64ToBytes(GroupPowers, bytes, i); i += 8;
|
|
bytes[i++] = (byte)GroupName.Length;
|
|
Buffer.BlockCopy(GroupName, 0, bytes, i, GroupName.Length); i += GroupName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public AgentDataUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentDataUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 387;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public AgentDataUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentDataUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentGroupDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
public ulong AgentPowers;
|
|
public byte[] GroupTitle;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 41;
|
|
if (GroupTitle != null) { length += GroupTitle.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AgentGroupDataBlock() { }
|
|
public AgentGroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
AgentPowers = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
length = bytes[i++];
|
|
GroupTitle = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, GroupTitle, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UInt64ToBytes(AgentPowers, bytes, i); i += 8;
|
|
bytes[i++] = (byte)GroupTitle.Length;
|
|
Buffer.BlockCopy(GroupTitle, 0, bytes, i, GroupTitle.Length); i += GroupTitle.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < AgentGroupData.Length; j++)
|
|
length += AgentGroupData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentGroupDataBlock[] AgentGroupData;
|
|
|
|
public GroupDataUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.GroupDataUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 388;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentGroupData = null;
|
|
}
|
|
|
|
public GroupDataUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(AgentGroupData == null || AgentGroupData.Length != -1) {
|
|
AgentGroupData = new AgentGroupDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentGroupData[j] = new AgentGroupDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentGroupData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public GroupDataUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(AgentGroupData == null || AgentGroupData.Length != count) {
|
|
AgentGroupData = new AgentGroupDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentGroupData[j] = new AgentGroupDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentGroupData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < AgentGroupData.Length; j++) { length += AgentGroupData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AgentGroupData.Length;
|
|
for (int j = 0; j < AgentGroupData.Length; j++) { AgentGroupData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int AgentGroupDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int AgentGroupDataCount = 0;
|
|
|
|
i = AgentGroupDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AgentGroupData.Length) {
|
|
int blockLength = AgentGroupData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AgentGroupDataStart) {
|
|
variableLength += blockLength;
|
|
++AgentGroupDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)AgentGroupDataCount;
|
|
for (i = AgentGroupDataStart; i < AgentGroupDataStart + AgentGroupDataCount; i++) { AgentGroupData[i].ToBytes(packet, ref length); }
|
|
AgentGroupDataStart += AgentGroupDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
AgentGroupDataStart < AgentGroupData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentGroupDataUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public ulong GroupPowers;
|
|
public bool AcceptNotices;
|
|
public UUID GroupInsigniaID;
|
|
public int Contribution;
|
|
public byte[] GroupName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 46;
|
|
if (GroupName != null) { length += GroupName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
GroupPowers = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
AcceptNotices = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
GroupInsigniaID.FromBytes(bytes, i); i += 16;
|
|
Contribution = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
GroupName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, GroupName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UInt64ToBytes(GroupPowers, bytes, i); i += 8;
|
|
bytes[i++] = (byte)((AcceptNotices) ? 1 : 0);
|
|
GroupInsigniaID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(Contribution, bytes, i); i += 4;
|
|
bytes[i++] = (byte)GroupName.Length;
|
|
Buffer.BlockCopy(GroupName, 0, bytes, i, GroupName.Length); i += GroupName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < GroupData.Length; j++)
|
|
length += GroupData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock[] GroupData;
|
|
|
|
public AgentGroupDataUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AgentGroupDataUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 389;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = null;
|
|
}
|
|
|
|
public AgentGroupDataUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(GroupData == null || GroupData.Length != -1) {
|
|
GroupData = new GroupDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ GroupData[j] = new GroupDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ GroupData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AgentGroupDataUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(GroupData == null || GroupData.Length != count) {
|
|
GroupData = new GroupDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ GroupData[j] = new GroupDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ GroupData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < GroupData.Length; j++) { length += GroupData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)GroupData.Length;
|
|
for (int j = 0; j < GroupData.Length; j++) { GroupData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int GroupDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int GroupDataCount = 0;
|
|
|
|
i = GroupDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < GroupData.Length) {
|
|
int blockLength = GroupData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == GroupDataStart) {
|
|
variableLength += blockLength;
|
|
++GroupDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)GroupDataCount;
|
|
for (i = GroupDataStart; i < GroupDataStart + GroupDataCount; i++) { GroupData[i].ToBytes(packet, ref length); }
|
|
GroupDataStart += GroupDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
GroupDataStart < GroupData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDropGroupPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public AgentDropGroupPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentDropGroup;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 390;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public AgentDropGroupPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentDropGroupPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RezSingleAttachmentFromInvPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID OwnerID;
|
|
public byte AttachmentPt;
|
|
public uint ItemFlags;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 51;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
AttachmentPt = (byte)bytes[i++];
|
|
ItemFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = AttachmentPt;
|
|
Utils.UIntToBytes(ItemFlags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock ObjectData;
|
|
|
|
public RezSingleAttachmentFromInvPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RezSingleAttachmentFromInv;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 395;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = new ObjectDataBlock();
|
|
}
|
|
|
|
public RezSingleAttachmentFromInvPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RezSingleAttachmentFromInvPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RezMultipleAttachmentsFromInvPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class HeaderDataBlock : PacketBlock
|
|
{
|
|
public UUID CompoundMsgID;
|
|
public byte TotalObjects;
|
|
public bool FirstDetachAll;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 18;
|
|
}
|
|
}
|
|
|
|
public HeaderDataBlock() { }
|
|
public HeaderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
CompoundMsgID.FromBytes(bytes, i); i += 16;
|
|
TotalObjects = (byte)bytes[i++];
|
|
FirstDetachAll = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
CompoundMsgID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = TotalObjects;
|
|
bytes[i++] = (byte)((FirstDetachAll) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID OwnerID;
|
|
public byte AttachmentPt;
|
|
public uint ItemFlags;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 51;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
AttachmentPt = (byte)bytes[i++];
|
|
ItemFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = AttachmentPt;
|
|
Utils.UIntToBytes(ItemFlags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += HeaderData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public HeaderDataBlock HeaderData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public RezMultipleAttachmentsFromInvPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.RezMultipleAttachmentsFromInv;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 396;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
HeaderData = new HeaderDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public RezMultipleAttachmentsFromInvPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
HeaderData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public RezMultipleAttachmentsFromInvPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
HeaderData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += HeaderData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
HeaderData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += HeaderData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
HeaderData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DetachAttachmentIntoInvPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += ObjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ObjectDataBlock ObjectData;
|
|
|
|
public DetachAttachmentIntoInvPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DetachAttachmentIntoInv;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 397;
|
|
Header.Reliable = true;
|
|
ObjectData = new ObjectDataBlock();
|
|
}
|
|
|
|
public DetachAttachmentIntoInvPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public DetachAttachmentIntoInvPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += ObjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CreateNewOutfitAttachmentsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class HeaderDataBlock : PacketBlock
|
|
{
|
|
public UUID NewFolderID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public HeaderDataBlock() { }
|
|
public HeaderDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
NewFolderID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
NewFolderID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID OldItemID;
|
|
public UUID OldFolderID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
OldItemID.FromBytes(bytes, i); i += 16;
|
|
OldFolderID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
OldItemID.ToBytes(bytes, i); i += 16;
|
|
OldFolderID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += HeaderData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public HeaderDataBlock HeaderData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public CreateNewOutfitAttachmentsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.CreateNewOutfitAttachments;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 398;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
HeaderData = new HeaderDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public CreateNewOutfitAttachmentsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
HeaderData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public CreateNewOutfitAttachmentsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
HeaderData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += HeaderData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
HeaderData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += HeaderData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
HeaderData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UserInfoRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public UserInfoRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.UserInfoRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 399;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public UserInfoRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public UserInfoRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UserInfoReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UserDataBlock : PacketBlock
|
|
{
|
|
public bool IMViaEMail;
|
|
public byte[] DirectoryVisibility;
|
|
public byte[] EMail;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 4;
|
|
if (DirectoryVisibility != null) { length += DirectoryVisibility.Length; }
|
|
if (EMail != null) { length += EMail.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public UserDataBlock() { }
|
|
public UserDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
IMViaEMail = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = bytes[i++];
|
|
DirectoryVisibility = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, DirectoryVisibility, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
EMail = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, EMail, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((IMViaEMail) ? 1 : 0);
|
|
bytes[i++] = (byte)DirectoryVisibility.Length;
|
|
Buffer.BlockCopy(DirectoryVisibility, 0, bytes, i, DirectoryVisibility.Length); i += DirectoryVisibility.Length;
|
|
bytes[i++] = (byte)(EMail.Length % 256);
|
|
bytes[i++] = (byte)((EMail.Length >> 8) % 256);
|
|
Buffer.BlockCopy(EMail, 0, bytes, i, EMail.Length); i += EMail.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += UserData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public UserDataBlock UserData;
|
|
|
|
public UserInfoReplyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.UserInfoReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 400;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
UserData = new UserDataBlock();
|
|
}
|
|
|
|
public UserInfoReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
UserData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public UserInfoReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
UserData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += UserData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
UserData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateUserInfoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UserDataBlock : PacketBlock
|
|
{
|
|
public bool IMViaEMail;
|
|
public byte[] DirectoryVisibility;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (DirectoryVisibility != null) { length += DirectoryVisibility.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public UserDataBlock() { }
|
|
public UserDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
IMViaEMail = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = bytes[i++];
|
|
DirectoryVisibility = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, DirectoryVisibility, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((IMViaEMail) ? 1 : 0);
|
|
bytes[i++] = (byte)DirectoryVisibility.Length;
|
|
Buffer.BlockCopy(DirectoryVisibility, 0, bytes, i, DirectoryVisibility.Length); i += DirectoryVisibility.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += UserData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public UserDataBlock UserData;
|
|
|
|
public UpdateUserInfoPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.UpdateUserInfo;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 401;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
UserData = new UserDataBlock();
|
|
}
|
|
|
|
public UpdateUserInfoPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
UserData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public UpdateUserInfoPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
UserData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += UserData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
UserData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InitiateDownloadPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FileDataBlock : PacketBlock
|
|
{
|
|
public byte[] SimFilename;
|
|
public byte[] ViewerFilename;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (SimFilename != null) { length += SimFilename.Length; }
|
|
if (ViewerFilename != null) { length += ViewerFilename.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public FileDataBlock() { }
|
|
public FileDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
SimFilename = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SimFilename, 0, length); i += length;
|
|
length = bytes[i++];
|
|
ViewerFilename = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ViewerFilename, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)SimFilename.Length;
|
|
Buffer.BlockCopy(SimFilename, 0, bytes, i, SimFilename.Length); i += SimFilename.Length;
|
|
bytes[i++] = (byte)ViewerFilename.Length;
|
|
Buffer.BlockCopy(ViewerFilename, 0, bytes, i, ViewerFilename.Length); i += ViewerFilename.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += FileData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public FileDataBlock FileData;
|
|
|
|
public InitiateDownloadPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.InitiateDownload;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 403;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
FileData = new FileDataBlock();
|
|
}
|
|
|
|
public InitiateDownloadPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
FileData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public InitiateDownloadPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
FileData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += FileData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
FileData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MapLayerRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint Flags;
|
|
public uint EstateID;
|
|
public bool Godlike;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 41;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EstateID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Godlike = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EstateID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((Godlike) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public MapLayerRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.MapLayerRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 405;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public MapLayerRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public MapLayerRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MapLayerReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LayerDataBlock : PacketBlock
|
|
{
|
|
public uint Left;
|
|
public uint Right;
|
|
public uint Top;
|
|
public uint Bottom;
|
|
public UUID ImageID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public LayerDataBlock() { }
|
|
public LayerDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Left = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Right = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Top = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Bottom = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ImageID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Left, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Right, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Top, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Bottom, bytes, i); i += 4;
|
|
ImageID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < LayerData.Length; j++)
|
|
length += LayerData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public LayerDataBlock[] LayerData;
|
|
|
|
public MapLayerReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.MapLayerReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 406;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
LayerData = null;
|
|
}
|
|
|
|
public MapLayerReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(LayerData == null || LayerData.Length != -1) {
|
|
LayerData = new LayerDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ LayerData[j] = new LayerDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ LayerData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public MapLayerReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(LayerData == null || LayerData.Length != count) {
|
|
LayerData = new LayerDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ LayerData[j] = new LayerDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ LayerData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < LayerData.Length; j++) { length += LayerData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)LayerData.Length;
|
|
for (int j = 0; j < LayerData.Length; j++) { LayerData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int LayerDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int LayerDataCount = 0;
|
|
|
|
i = LayerDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < LayerData.Length) {
|
|
int blockLength = LayerData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == LayerDataStart) {
|
|
variableLength += blockLength;
|
|
++LayerDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)LayerDataCount;
|
|
for (i = LayerDataStart; i < LayerDataStart + LayerDataCount; i++) { LayerData[i].ToBytes(packet, ref length); }
|
|
LayerDataStart += LayerDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
LayerDataStart < LayerData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MapBlockRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint Flags;
|
|
public uint EstateID;
|
|
public bool Godlike;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 41;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EstateID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Godlike = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EstateID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((Godlike) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PositionDataBlock : PacketBlock
|
|
{
|
|
public ushort MinX;
|
|
public ushort MaxX;
|
|
public ushort MinY;
|
|
public ushort MaxY;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
public PositionDataBlock() { }
|
|
public PositionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
MinX = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
MaxX = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
MinY = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
MaxY = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(MinX % 256);
|
|
bytes[i++] = (byte)((MinX >> 8) % 256);
|
|
bytes[i++] = (byte)(MaxX % 256);
|
|
bytes[i++] = (byte)((MaxX >> 8) % 256);
|
|
bytes[i++] = (byte)(MinY % 256);
|
|
bytes[i++] = (byte)((MinY >> 8) % 256);
|
|
bytes[i++] = (byte)(MaxY % 256);
|
|
bytes[i++] = (byte)((MaxY >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += PositionData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public PositionDataBlock PositionData;
|
|
|
|
public MapBlockRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.MapBlockRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 407;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
PositionData = new PositionDataBlock();
|
|
}
|
|
|
|
public MapBlockRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
PositionData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public MapBlockRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
PositionData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += PositionData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
PositionData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MapNameRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint Flags;
|
|
public uint EstateID;
|
|
public bool Godlike;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 41;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EstateID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Godlike = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EstateID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((Godlike) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class NameDataBlock : PacketBlock
|
|
{
|
|
public byte[] Name;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public NameDataBlock() { }
|
|
public NameDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += NameData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public NameDataBlock NameData;
|
|
|
|
public MapNameRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.MapNameRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 408;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
NameData = new NameDataBlock();
|
|
}
|
|
|
|
public MapNameRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
NameData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public MapNameRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
NameData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += NameData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
NameData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MapBlockReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public ushort X;
|
|
public ushort Y;
|
|
public byte[] Name;
|
|
public byte Access;
|
|
public uint RegionFlags;
|
|
public byte WaterHeight;
|
|
public byte Agents;
|
|
public UUID MapImageID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 28;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
X = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
Y = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
Access = (byte)bytes[i++];
|
|
RegionFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
WaterHeight = (byte)bytes[i++];
|
|
Agents = (byte)bytes[i++];
|
|
MapImageID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(X % 256);
|
|
bytes[i++] = (byte)((X >> 8) % 256);
|
|
bytes[i++] = (byte)(Y % 256);
|
|
bytes[i++] = (byte)((Y >> 8) % 256);
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = Access;
|
|
Utils.UIntToBytes(RegionFlags, bytes, i); i += 4;
|
|
bytes[i++] = WaterHeight;
|
|
bytes[i++] = Agents;
|
|
MapImageID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SizeBlock : PacketBlock
|
|
{
|
|
public ushort SizeX;
|
|
public ushort SizeY;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public SizeBlock() { }
|
|
public SizeBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
SizeX = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
SizeY = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(SizeX % 256);
|
|
bytes[i++] = (byte)((SizeX >> 8) % 256);
|
|
bytes[i++] = (byte)(SizeY % 256);
|
|
bytes[i++] = (byte)((SizeY >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 12;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
for (int j = 0; j < Size.Length; j++)
|
|
length += Size[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock[] Data;
|
|
public SizeBlock[] Size;
|
|
|
|
public MapBlockReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.MapBlockReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 409;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = null;
|
|
Size = null;
|
|
}
|
|
|
|
public MapBlockReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(Size == null || Size.Length != -1) {
|
|
Size = new SizeBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Size[j] = new SizeBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Size[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public MapBlockReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(Size == null || Size.Length != count) {
|
|
Size = new SizeBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Size[j] = new SizeBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Size[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < Size.Length; j++) { length += Size[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)Size.Length;
|
|
for (int j = 0; j < Size.Length; j++) { Size[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int DataStart = 0;
|
|
int SizeStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
int SizeCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = SizeStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Size.Length) {
|
|
int blockLength = Size[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == SizeStart) {
|
|
variableLength += blockLength;
|
|
++SizeCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
packet[length++] = (byte)SizeCount;
|
|
for (i = SizeStart; i < SizeStart + SizeCount; i++) { Size[i].ToBytes(packet, ref length); }
|
|
SizeStart += SizeCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length ||
|
|
SizeStart < Size.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MapItemRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public uint Flags;
|
|
public uint EstateID;
|
|
public bool Godlike;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 41;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EstateID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Godlike = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EstateID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((Godlike) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestDataBlock : PacketBlock
|
|
{
|
|
public uint ItemType;
|
|
public ulong RegionHandle;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public RequestDataBlock() { }
|
|
public RequestDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemType = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ItemType, bytes, i); i += 4;
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RequestData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RequestDataBlock RequestData;
|
|
|
|
public MapItemRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.MapItemRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 410;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
RequestData = new RequestDataBlock();
|
|
}
|
|
|
|
public MapItemRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RequestData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public MapItemRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RequestData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RequestData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
RequestData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MapItemReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestDataBlock : PacketBlock
|
|
{
|
|
public uint ItemType;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public RequestDataBlock() { }
|
|
public RequestDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ItemType = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ItemType, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public uint X;
|
|
public uint Y;
|
|
public UUID ID;
|
|
public int Extra;
|
|
public int Extra2;
|
|
public byte[] Name;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 33;
|
|
if (Name != null) { length += Name.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
X = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Y = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
Extra = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Extra2 = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(X, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Y, bytes, i); i += 4;
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(Extra, bytes, i); i += 4;
|
|
Utils.IntToBytes(Extra2, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += RequestData.Length;
|
|
for (int j = 0; j < Data.Length; j++)
|
|
length += Data[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RequestDataBlock RequestData;
|
|
public DataBlock[] Data;
|
|
|
|
public MapItemReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.MapItemReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 411;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
RequestData = new RequestDataBlock();
|
|
Data = null;
|
|
}
|
|
|
|
public MapItemReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RequestData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != -1) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public MapItemReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RequestData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Data == null || Data.Length != count) {
|
|
Data = new DataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Data[j] = new DataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Data[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RequestData.Length;
|
|
length++;
|
|
for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
RequestData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Data.Length;
|
|
for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += RequestData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
RequestData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataCount = 0;
|
|
|
|
i = DataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) {
|
|
int blockLength = Data[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataStart) {
|
|
variableLength += blockLength;
|
|
++DataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataCount;
|
|
for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); }
|
|
DataStart += DataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataStart < Data.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SendPostcardPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID AssetID;
|
|
public Vector3d PosGlobal;
|
|
public byte[] To;
|
|
public byte[] From;
|
|
public byte[] Name;
|
|
public byte[] Subject;
|
|
public byte[] Msg;
|
|
public bool AllowPublish;
|
|
public bool MaturePublish;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 80;
|
|
if (To != null) { length += To.Length; }
|
|
if (From != null) { length += From.Length; }
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Subject != null) { length += Subject.Length; }
|
|
if (Msg != null) { length += Msg.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
AssetID.FromBytes(bytes, i); i += 16;
|
|
PosGlobal.FromBytes(bytes, i); i += 24;
|
|
length = bytes[i++];
|
|
To = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, To, 0, length); i += length;
|
|
length = bytes[i++];
|
|
From = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, From, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Subject = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Subject, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Msg = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Msg, 0, length); i += length;
|
|
AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
AssetID.ToBytes(bytes, i); i += 16;
|
|
PosGlobal.ToBytes(bytes, i); i += 24;
|
|
bytes[i++] = (byte)To.Length;
|
|
Buffer.BlockCopy(To, 0, bytes, i, To.Length); i += To.Length;
|
|
bytes[i++] = (byte)From.Length;
|
|
Buffer.BlockCopy(From, 0, bytes, i, From.Length); i += From.Length;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Subject.Length;
|
|
Buffer.BlockCopy(Subject, 0, bytes, i, Subject.Length); i += Subject.Length;
|
|
bytes[i++] = (byte)(Msg.Length % 256);
|
|
bytes[i++] = (byte)((Msg.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Msg, 0, bytes, i, Msg.Length); i += Msg.Length;
|
|
bytes[i++] = (byte)((AllowPublish) ? 1 : 0);
|
|
bytes[i++] = (byte)((MaturePublish) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public SendPostcardPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SendPostcard;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 412;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public SendPostcardPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SendPostcardPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelMediaCommandMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class CommandBlockBlock : PacketBlock
|
|
{
|
|
public uint Flags;
|
|
public uint Command;
|
|
public float Time;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public CommandBlockBlock() { }
|
|
public CommandBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Command = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Time = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Command, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Time, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += CommandBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public CommandBlockBlock CommandBlock;
|
|
|
|
public ParcelMediaCommandMessagePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelMediaCommandMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 419;
|
|
Header.Reliable = true;
|
|
CommandBlock = new CommandBlockBlock();
|
|
}
|
|
|
|
public ParcelMediaCommandMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
CommandBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelMediaCommandMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
CommandBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += CommandBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
CommandBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelMediaUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlockBlock : PacketBlock
|
|
{
|
|
public byte[] MediaURL;
|
|
public UUID MediaID;
|
|
public byte MediaAutoScale;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 18;
|
|
if (MediaURL != null) { length += MediaURL.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlockBlock() { }
|
|
public DataBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
MediaURL = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MediaURL, 0, length); i += length;
|
|
MediaID.FromBytes(bytes, i); i += 16;
|
|
MediaAutoScale = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)MediaURL.Length;
|
|
Buffer.BlockCopy(MediaURL, 0, bytes, i, MediaURL.Length); i += MediaURL.Length;
|
|
MediaID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = MediaAutoScale;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlockExtendedBlock : PacketBlock
|
|
{
|
|
public byte[] MediaType;
|
|
public byte[] MediaDesc;
|
|
public int MediaWidth;
|
|
public int MediaHeight;
|
|
public byte MediaLoop;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
if (MediaType != null) { length += MediaType.Length; }
|
|
if (MediaDesc != null) { length += MediaDesc.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlockExtendedBlock() { }
|
|
public DataBlockExtendedBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
MediaType = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MediaType, 0, length); i += length;
|
|
length = bytes[i++];
|
|
MediaDesc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MediaDesc, 0, length); i += length;
|
|
MediaWidth = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
MediaHeight = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
MediaLoop = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)MediaType.Length;
|
|
Buffer.BlockCopy(MediaType, 0, bytes, i, MediaType.Length); i += MediaType.Length;
|
|
bytes[i++] = (byte)MediaDesc.Length;
|
|
Buffer.BlockCopy(MediaDesc, 0, bytes, i, MediaDesc.Length); i += MediaDesc.Length;
|
|
Utils.IntToBytes(MediaWidth, bytes, i); i += 4;
|
|
Utils.IntToBytes(MediaHeight, bytes, i); i += 4;
|
|
bytes[i++] = MediaLoop;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += DataBlock.Length;
|
|
length += DataBlockExtended.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlockBlock DataBlock;
|
|
public DataBlockExtendedBlock DataBlockExtended;
|
|
|
|
public ParcelMediaUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelMediaUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 420;
|
|
Header.Reliable = true;
|
|
DataBlock = new DataBlockBlock();
|
|
DataBlockExtended = new DataBlockExtendedBlock();
|
|
}
|
|
|
|
public ParcelMediaUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
DataBlockExtended.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelMediaUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
DataBlockExtended.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += DataBlock.Length;
|
|
length += DataBlockExtended.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
DataBlock.ToBytes(bytes, ref i);
|
|
DataBlockExtended.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LandStatRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestDataBlock : PacketBlock
|
|
{
|
|
public uint ReportType;
|
|
public uint RequestFlags;
|
|
public byte[] Filter;
|
|
public int ParcelLocalID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 13;
|
|
if (Filter != null) { length += Filter.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RequestDataBlock() { }
|
|
public RequestDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ReportType = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RequestFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Filter = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Filter, 0, length); i += length;
|
|
ParcelLocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ReportType, bytes, i); i += 4;
|
|
Utils.UIntToBytes(RequestFlags, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Filter.Length;
|
|
Buffer.BlockCopy(Filter, 0, bytes, i, Filter.Length); i += Filter.Length;
|
|
Utils.IntToBytes(ParcelLocalID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RequestData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RequestDataBlock RequestData;
|
|
|
|
public LandStatRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.LandStatRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 421;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
RequestData = new RequestDataBlock();
|
|
}
|
|
|
|
public LandStatRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RequestData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public LandStatRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RequestData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RequestData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
RequestData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LandStatReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class RequestDataBlock : PacketBlock
|
|
{
|
|
public uint ReportType;
|
|
public uint RequestFlags;
|
|
public uint TotalObjectCount;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public RequestDataBlock() { }
|
|
public RequestDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ReportType = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RequestFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TotalObjectCount = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ReportType, bytes, i); i += 4;
|
|
Utils.UIntToBytes(RequestFlags, bytes, i); i += 4;
|
|
Utils.UIntToBytes(TotalObjectCount, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ReportDataBlock : PacketBlock
|
|
{
|
|
public uint TaskLocalID;
|
|
public UUID TaskID;
|
|
public float LocationX;
|
|
public float LocationY;
|
|
public float LocationZ;
|
|
public float Score;
|
|
public byte[] TaskName;
|
|
public byte[] OwnerName;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 38;
|
|
if (TaskName != null) { length += TaskName.Length; }
|
|
if (OwnerName != null) { length += OwnerName.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ReportDataBlock() { }
|
|
public ReportDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TaskLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TaskID.FromBytes(bytes, i); i += 16;
|
|
LocationX = Utils.BytesToFloat(bytes, i); i += 4;
|
|
LocationY = Utils.BytesToFloat(bytes, i); i += 4;
|
|
LocationZ = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Score = Utils.BytesToFloat(bytes, i); i += 4;
|
|
length = bytes[i++];
|
|
TaskName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TaskName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
OwnerName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, OwnerName, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(TaskLocalID, bytes, i); i += 4;
|
|
TaskID.ToBytes(bytes, i); i += 16;
|
|
Utils.FloatToBytes(LocationX, bytes, i); i += 4;
|
|
Utils.FloatToBytes(LocationY, bytes, i); i += 4;
|
|
Utils.FloatToBytes(LocationZ, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Score, bytes, i); i += 4;
|
|
bytes[i++] = (byte)TaskName.Length;
|
|
Buffer.BlockCopy(TaskName, 0, bytes, i, TaskName.Length); i += TaskName.Length;
|
|
bytes[i++] = (byte)OwnerName.Length;
|
|
Buffer.BlockCopy(OwnerName, 0, bytes, i, OwnerName.Length); i += OwnerName.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += RequestData.Length;
|
|
for (int j = 0; j < ReportData.Length; j++)
|
|
length += ReportData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RequestDataBlock RequestData;
|
|
public ReportDataBlock[] ReportData;
|
|
|
|
public LandStatReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.LandStatReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 422;
|
|
Header.Reliable = true;
|
|
RequestData = new RequestDataBlock();
|
|
ReportData = null;
|
|
}
|
|
|
|
public LandStatReplyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
RequestData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ReportData == null || ReportData.Length != -1) {
|
|
ReportData = new ReportDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ReportData[j] = new ReportDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ReportData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public LandStatReplyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
RequestData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ReportData == null || ReportData.Length != count) {
|
|
ReportData = new ReportDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ReportData[j] = new ReportDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ReportData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += RequestData.Length;
|
|
length++;
|
|
for (int j = 0; j < ReportData.Length; j++) { length += ReportData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RequestData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ReportData.Length;
|
|
for (int j = 0; j < ReportData.Length; j++) { ReportData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += RequestData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
RequestData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ReportDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ReportDataCount = 0;
|
|
|
|
i = ReportDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ReportData.Length) {
|
|
int blockLength = ReportData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ReportDataStart) {
|
|
variableLength += blockLength;
|
|
++ReportDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ReportDataCount;
|
|
for (i = ReportDataStart; i < ReportDataStart + ReportDataCount; i++) { ReportData[i].ToBytes(packet, ref length); }
|
|
ReportDataStart += ReportDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ReportDataStart < ReportData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ErrorPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlock : PacketBlock
|
|
{
|
|
public int Code;
|
|
public byte[] Token;
|
|
public UUID ID;
|
|
public byte[] System;
|
|
public byte[] Message;
|
|
public byte[] Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 26;
|
|
if (Token != null) { length += Token.Length; }
|
|
if (System != null) { length += System.Length; }
|
|
if (Message != null) { length += Message.Length; }
|
|
if (Data != null) { length += Data.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlock() { }
|
|
public DataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
Code = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Token = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Token, 0, length); i += length;
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
System = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, System, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Message, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(Code, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Token.Length;
|
|
Buffer.BlockCopy(Token, 0, bytes, i, Token.Length); i += Token.Length;
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)System.Length;
|
|
Buffer.BlockCopy(System, 0, bytes, i, System.Length); i += System.Length;
|
|
bytes[i++] = (byte)(Message.Length % 256);
|
|
bytes[i++] = (byte)((Message.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Message, 0, bytes, i, Message.Length); i += Message.Length;
|
|
bytes[i++] = (byte)(Data.Length % 256);
|
|
bytes[i++] = (byte)((Data.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public DataBlock Data;
|
|
|
|
public ErrorPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.Error;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 423;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
public ErrorPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ErrorPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
Data.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += Data.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
Data.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectIncludeInSearchPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public bool IncludeInSearch;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 5;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
IncludeInSearch = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((IncludeInSearch) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectIncludeInSearchPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectIncludeInSearch;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 424;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectIncludeInSearchPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectIncludeInSearchPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RezRestoreToWorldPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
public UUID CreatorID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public bool GroupOwned;
|
|
public UUID TransactionID;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public uint Flags;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public int CreationDate;
|
|
public uint CRC;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 138;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryDataBlock() { }
|
|
public InventoryDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
CreationDate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((GroupOwned) ? 1 : 0);
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
Utils.IntToBytes(CreationDate, bytes, i); i += 4;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryDataBlock InventoryData;
|
|
|
|
public RezRestoreToWorldPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RezRestoreToWorld;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 425;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryData = new InventoryDataBlock();
|
|
}
|
|
|
|
public RezRestoreToWorldPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RezRestoreToWorldPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
InventoryData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LinkInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InventoryBlockBlock : PacketBlock
|
|
{
|
|
public uint CallbackID;
|
|
public UUID FolderID;
|
|
public UUID TransactionID;
|
|
public UUID OldItemID;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 56;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public InventoryBlockBlock() { }
|
|
public InventoryBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
CallbackID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
OldItemID.FromBytes(bytes, i); i += 16;
|
|
Type = (sbyte)bytes[i++];
|
|
InvType = (sbyte)bytes[i++];
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(CallbackID, bytes, i); i += 4;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
OldItemID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Type;
|
|
bytes[i++] = (byte)InvType;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public InventoryBlockBlock InventoryBlock;
|
|
|
|
public LinkInventoryItemPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.LinkInventoryItem;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 426;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
InventoryBlock = new InventoryBlockBlock();
|
|
}
|
|
|
|
public LinkInventoryItemPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public LinkInventoryItemPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
InventoryBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += InventoryBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
InventoryBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RetrieveIMsExtendedPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public bool IsPremium;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
IsPremium = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsPremium) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public RetrieveIMsExtendedPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RetrieveIMsExtended;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 427;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public RetrieveIMsExtendedPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RetrieveIMsExtendedPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class JoinGroupRequestExtendedPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public int GroupLimit;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupLimit = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(GroupLimit, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public JoinGroupRequestExtendedPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.JoinGroupRequestExtended;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 428;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public JoinGroupRequestExtendedPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public JoinGroupRequestExtendedPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CreateGroupRequestExtendedPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public int GroupLimit;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 36;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupLimit = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(GroupLimit, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public byte[] Name;
|
|
public byte[] Charter;
|
|
public bool ShowInList;
|
|
public UUID InsigniaID;
|
|
public int MembershipFee;
|
|
public bool OpenEnrollment;
|
|
public bool AllowPublish;
|
|
public bool MaturePublish;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 27;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Charter != null) { length += Charter.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Charter = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Charter, 0, length); i += length;
|
|
ShowInList = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
InsigniaID.FromBytes(bytes, i); i += 16;
|
|
MembershipFee = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OpenEnrollment = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
AllowPublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
MaturePublish = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)(Charter.Length % 256);
|
|
bytes[i++] = (byte)((Charter.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Charter, 0, bytes, i, Charter.Length); i += Charter.Length;
|
|
bytes[i++] = (byte)((ShowInList) ? 1 : 0);
|
|
InsigniaID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(MembershipFee, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((OpenEnrollment) ? 1 : 0);
|
|
bytes[i++] = (byte)((AllowPublish) ? 1 : 0);
|
|
bytes[i++] = (byte)((MaturePublish) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock GroupData;
|
|
|
|
public CreateGroupRequestExtendedPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CreateGroupRequestExtended;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 429;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = new GroupDataBlock();
|
|
}
|
|
|
|
public CreateGroupRequestExtendedPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public CreateGroupRequestExtendedPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
GroupData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += GroupData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
GroupData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LargeGenericMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID TransactionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
TransactionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
TransactionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MethodDataBlock : PacketBlock
|
|
{
|
|
public byte[] Method;
|
|
public UUID Invoice;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 17;
|
|
if (Method != null) { length += Method.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public MethodDataBlock() { }
|
|
public MethodDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Method = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Method, 0, length); i += length;
|
|
Invoice.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Method.Length;
|
|
Buffer.BlockCopy(Method, 0, bytes, i, Method.Length); i += Method.Length;
|
|
Invoice.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParamListBlock : PacketBlock
|
|
{
|
|
public byte[] Parameter;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (Parameter != null) { length += Parameter.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ParamListBlock() { }
|
|
public ParamListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Parameter = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Parameter, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(Parameter.Length % 256);
|
|
bytes[i++] = (byte)((Parameter.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Parameter, 0, bytes, i, Parameter.Length); i += Parameter.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += AgentData.Length;
|
|
length += MethodData.Length;
|
|
for (int j = 0; j < ParamList.Length; j++)
|
|
length += ParamList[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MethodDataBlock MethodData;
|
|
public ParamListBlock[] ParamList;
|
|
|
|
public LargeGenericMessagePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.LargeGenericMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 430;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
MethodData = new MethodDataBlock();
|
|
ParamList = null;
|
|
}
|
|
|
|
public LargeGenericMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MethodData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParamList == null || ParamList.Length != -1) {
|
|
ParamList = new ParamListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParamList[j] = new ParamListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParamList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public LargeGenericMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
MethodData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ParamList == null || ParamList.Length != count) {
|
|
ParamList = new ParamListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ParamList[j] = new ParamListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ParamList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MethodData.Length;
|
|
length++;
|
|
for (int j = 0; j < ParamList.Length; j++) { length += ParamList[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
MethodData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ParamList.Length;
|
|
for (int j = 0; j < ParamList.Length; j++) { ParamList[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
fixedLength += MethodData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
MethodData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ParamListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ParamListCount = 0;
|
|
|
|
i = ParamListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ParamList.Length) {
|
|
int blockLength = ParamList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ParamListStart) {
|
|
variableLength += blockLength;
|
|
++ParamListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ParamListCount;
|
|
for (i = ParamListStart; i < ParamListStart + ParamListCount; i++) { ParamList[i].ToBytes(packet, ref length); }
|
|
ParamListStart += ParamListCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ParamListStart < ParamList.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PacketAckPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PacketsBlock : PacketBlock
|
|
{
|
|
public uint ID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public PacketsBlock() { }
|
|
public PacketsBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
for (int j = 0; j < Packets.Length; j++)
|
|
length += Packets[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public PacketsBlock[] Packets;
|
|
|
|
public PacketAckPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.PacketAck;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 65531;
|
|
Header.Reliable = true;
|
|
Packets = null;
|
|
}
|
|
|
|
public PacketAckPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if (Packets == null || Packets.Length != -1)
|
|
{
|
|
Packets = new PacketsBlock[count];
|
|
for (int j = 0; j < count; j++)
|
|
{ Packets[j] = new PacketsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Packets[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public PacketAckPacket(Header head, byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if (Packets == null || Packets.Length != count)
|
|
{
|
|
Packets = new PacketsBlock[count];
|
|
for (int j = 0; j < count; j++)
|
|
{ Packets[j] = new PacketsBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Packets[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < Packets.Length; j++) { length += Packets[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Packets.Length;
|
|
for (int j = 0; j < Packets.Length; j++) { Packets[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int PacketsStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int PacketsCount = 0;
|
|
|
|
i = PacketsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Packets.Length)
|
|
{
|
|
int blockLength = Packets[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == PacketsStart)
|
|
{
|
|
variableLength += blockLength;
|
|
++PacketsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)PacketsCount;
|
|
for (i = PacketsStart; i < PacketsStart + PacketsCount; i++) { Packets[i].ToBytes(packet, ref length); }
|
|
PacketsStart += PacketsCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
PacketsStart < Packets.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 10;
|
|
length++;
|
|
for (int j = 0; j < Packets.Length; j++) { length += Packets[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Packets.Length;
|
|
for (int j = 0; j < Packets.Length; j++) { Packets[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
System.Collections.Generic.List<int> retSizes = new System.Collections.Generic.List<int>();
|
|
|
|
int i = 0;
|
|
int fixedLength = 10;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int PacketsStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int PacketsCount = 0;
|
|
|
|
i = PacketsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Packets.Length)
|
|
{
|
|
int blockLength = Packets[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++PacketsCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
int packetSize = fixedLength + variableLength + acksLength;
|
|
byte[] packet = pool.LeaseBytes(packetSize);
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)PacketsCount;
|
|
for (i = PacketsStart; i < PacketsStart + PacketsCount; i++) { Packets[i].ToBytes(packet, ref length); }
|
|
PacketsStart += PacketsCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
retSizes.Add(packetSize);
|
|
packets.Add(packet);
|
|
} while (
|
|
PacketsStart < Packets.Length);
|
|
|
|
sizes = retSizes.ToArray();
|
|
return packets.ToArray();
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class OpenCircuitPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class CircuitInfoBlock : PacketBlock
|
|
{
|
|
public uint IP;
|
|
public ushort Port;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 6;
|
|
}
|
|
}
|
|
|
|
public CircuitInfoBlock() { }
|
|
public CircuitInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
IP = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Port = (ushort)((bytes[i++] << 8) + bytes[i++]);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(IP, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((Port >> 8) % 256);
|
|
bytes[i++] = (byte)(Port % 256);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += CircuitInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public CircuitInfoBlock CircuitInfo;
|
|
|
|
public OpenCircuitPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.OpenCircuit;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 65532;
|
|
Header.Reliable = true;
|
|
CircuitInfo = new CircuitInfoBlock();
|
|
}
|
|
|
|
public OpenCircuitPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
CircuitInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public OpenCircuitPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
CircuitInfo.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += CircuitInfo.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
CircuitInfo.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CloseCircuitPacket : Packet
|
|
{
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public CloseCircuitPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CloseCircuit;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 65533;
|
|
Header.Reliable = true;
|
|
}
|
|
|
|
public CloseCircuitPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
}
|
|
|
|
public CloseCircuitPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectAddPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID GroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public byte PCode;
|
|
public byte Material;
|
|
public uint AddFlags;
|
|
public byte PathCurve;
|
|
public byte ProfileCurve;
|
|
public ushort PathBegin;
|
|
public ushort PathEnd;
|
|
public byte PathScaleX;
|
|
public byte PathScaleY;
|
|
public byte PathShearX;
|
|
public byte PathShearY;
|
|
public sbyte PathTwist;
|
|
public sbyte PathTwistBegin;
|
|
public sbyte PathRadiusOffset;
|
|
public sbyte PathTaperX;
|
|
public sbyte PathTaperY;
|
|
public byte PathRevolutions;
|
|
public sbyte PathSkew;
|
|
public ushort ProfileBegin;
|
|
public ushort ProfileEnd;
|
|
public ushort ProfileHollow;
|
|
public byte BypassRaycast;
|
|
public Vector3 RayStart;
|
|
public Vector3 RayEnd;
|
|
public UUID RayTargetID;
|
|
public byte RayEndIsIntersection;
|
|
public Vector3 Scale;
|
|
public Quaternion Rotation;
|
|
public byte State;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 96;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
PCode = (byte)bytes[i++];
|
|
Material = (byte)bytes[i++];
|
|
AddFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PathCurve = (byte)bytes[i++];
|
|
ProfileCurve = (byte)bytes[i++];
|
|
PathBegin = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
PathEnd = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
PathScaleX = (byte)bytes[i++];
|
|
PathScaleY = (byte)bytes[i++];
|
|
PathShearX = (byte)bytes[i++];
|
|
PathShearY = (byte)bytes[i++];
|
|
PathTwist = (sbyte)bytes[i++];
|
|
PathTwistBegin = (sbyte)bytes[i++];
|
|
PathRadiusOffset = (sbyte)bytes[i++];
|
|
PathTaperX = (sbyte)bytes[i++];
|
|
PathTaperY = (sbyte)bytes[i++];
|
|
PathRevolutions = (byte)bytes[i++];
|
|
PathSkew = (sbyte)bytes[i++];
|
|
ProfileBegin = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
ProfileEnd = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
ProfileHollow = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
BypassRaycast = (byte)bytes[i++];
|
|
RayStart.FromBytes(bytes, i); i += 12;
|
|
RayEnd.FromBytes(bytes, i); i += 12;
|
|
RayTargetID.FromBytes(bytes, i); i += 16;
|
|
RayEndIsIntersection = (byte)bytes[i++];
|
|
Scale.FromBytes(bytes, i); i += 12;
|
|
Rotation.FromBytes(bytes, i, true); i += 12;
|
|
State = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = PCode;
|
|
bytes[i++] = Material;
|
|
Utils.UIntToBytes(AddFlags, bytes, i); i += 4;
|
|
bytes[i++] = PathCurve;
|
|
bytes[i++] = ProfileCurve;
|
|
bytes[i++] = (byte)(PathBegin % 256);
|
|
bytes[i++] = (byte)((PathBegin >> 8) % 256);
|
|
bytes[i++] = (byte)(PathEnd % 256);
|
|
bytes[i++] = (byte)((PathEnd >> 8) % 256);
|
|
bytes[i++] = PathScaleX;
|
|
bytes[i++] = PathScaleY;
|
|
bytes[i++] = PathShearX;
|
|
bytes[i++] = PathShearY;
|
|
bytes[i++] = (byte)PathTwist;
|
|
bytes[i++] = (byte)PathTwistBegin;
|
|
bytes[i++] = (byte)PathRadiusOffset;
|
|
bytes[i++] = (byte)PathTaperX;
|
|
bytes[i++] = (byte)PathTaperY;
|
|
bytes[i++] = PathRevolutions;
|
|
bytes[i++] = (byte)PathSkew;
|
|
bytes[i++] = (byte)(ProfileBegin % 256);
|
|
bytes[i++] = (byte)((ProfileBegin >> 8) % 256);
|
|
bytes[i++] = (byte)(ProfileEnd % 256);
|
|
bytes[i++] = (byte)((ProfileEnd >> 8) % 256);
|
|
bytes[i++] = (byte)(ProfileHollow % 256);
|
|
bytes[i++] = (byte)((ProfileHollow >> 8) % 256);
|
|
bytes[i++] = BypassRaycast;
|
|
RayStart.ToBytes(bytes, i); i += 12;
|
|
RayEnd.ToBytes(bytes, i); i += 12;
|
|
RayTargetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = RayEndIsIntersection;
|
|
Scale.ToBytes(bytes, i); i += 12;
|
|
Rotation.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = State;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock ObjectData;
|
|
|
|
public ObjectAddPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ObjectAdd;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 1;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = new ObjectDataBlock();
|
|
}
|
|
|
|
public ObjectAddPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ObjectAddPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MultipleObjectUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public byte Type;
|
|
public byte[] Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 6;
|
|
if (Data != null) { length += Data.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Type = (byte)bytes[i++];
|
|
length = bytes[i++];
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
bytes[i++] = Type;
|
|
bytes[i++] = (byte)Data.Length;
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 9;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public MultipleObjectUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.MultipleObjectUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 2;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public MultipleObjectUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public MultipleObjectUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 8;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestMultipleObjectsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public byte CacheMissType;
|
|
public uint ID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 5;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
CacheMissType = (byte)bytes[i++];
|
|
ID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = CacheMissType;
|
|
Utils.UIntToBytes(ID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 9;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public RequestMultipleObjectsPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.RequestMultipleObjects;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 3;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public RequestMultipleObjectsPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public RequestMultipleObjectsPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 8;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectPositionPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public Vector3 Position;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectLocalID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ObjectLocalID, bytes, i); i += 4;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 9;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectPositionPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectPosition;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 4;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectPositionPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectPositionPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 8;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestObjectPropertiesFamilyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint RequestFlags;
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RequestFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(RequestFlags, bytes, i); i += 4;
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ObjectDataBlock ObjectData;
|
|
|
|
public RequestObjectPropertiesFamilyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RequestObjectPropertiesFamily;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 5;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ObjectData = new ObjectDataBlock();
|
|
}
|
|
|
|
public RequestObjectPropertiesFamilyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RequestObjectPropertiesFamilyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length += ObjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CoarseLocationUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class LocationBlock : PacketBlock
|
|
{
|
|
public byte X;
|
|
public byte Y;
|
|
public byte Z;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
public LocationBlock() { }
|
|
public LocationBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
X = (byte)bytes[i++];
|
|
Y = (byte)bytes[i++];
|
|
Z = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = X;
|
|
bytes[i++] = Y;
|
|
bytes[i++] = Z;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class IndexBlock : PacketBlock
|
|
{
|
|
public short You;
|
|
public short Prey;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public IndexBlock() { }
|
|
public IndexBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
You = (short)(bytes[i++] + (bytes[i++] << 8));
|
|
Prey = (short)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(You % 256);
|
|
bytes[i++] = (byte)((You >> 8) % 256);
|
|
bytes[i++] = (byte)(Prey % 256);
|
|
bytes[i++] = (byte)((Prey >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
for (int j = 0; j < Location.Length; j++)
|
|
length += Location[j].Length;
|
|
length += Index.Length;
|
|
for (int j = 0; j < AgentData.Length; j++)
|
|
length += AgentData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public LocationBlock[] Location;
|
|
public IndexBlock Index;
|
|
public AgentDataBlock[] AgentData;
|
|
|
|
public CoarseLocationUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.CoarseLocationUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 6;
|
|
Header.Reliable = true;
|
|
Location = null;
|
|
Index = new IndexBlock();
|
|
AgentData = null;
|
|
}
|
|
|
|
public CoarseLocationUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(Location == null || Location.Length != -1) {
|
|
Location = new LocationBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Location[j] = new LocationBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Location[j].FromBytes(bytes, ref i); }
|
|
Index.FromBytes(bytes, ref i);
|
|
count = (int)bytes[i++];
|
|
if(AgentData == null || AgentData.Length != -1) {
|
|
AgentData = new AgentDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentData[j] = new AgentDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public CoarseLocationUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(Location == null || Location.Length != count) {
|
|
Location = new LocationBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Location[j] = new LocationBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Location[j].FromBytes(bytes, ref i); }
|
|
Index.FromBytes(bytes, ref i);
|
|
count = (int)bytes[i++];
|
|
if(AgentData == null || AgentData.Length != count) {
|
|
AgentData = new AgentDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentData[j] = new AgentDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += Index.Length;
|
|
length++;
|
|
for (int j = 0; j < Location.Length; j++) { length += Location[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AgentData.Length; j++) { length += AgentData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Location.Length;
|
|
for (int j = 0; j < Location.Length; j++) { Location[j].ToBytes(bytes, ref i); }
|
|
Index.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AgentData.Length;
|
|
for (int j = 0; j < AgentData.Length; j++) { AgentData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CrossedRegionPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionDataBlock : PacketBlock
|
|
{
|
|
public uint SimIP;
|
|
public ushort SimPort;
|
|
public ulong RegionHandle;
|
|
public byte[] SeedCapability;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 16;
|
|
if (SeedCapability != null) { length += SeedCapability.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RegionDataBlock() { }
|
|
public RegionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
SimIP = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SimPort = (ushort)((bytes[i++] << 8) + bytes[i++]);
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
SeedCapability = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SeedCapability, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(SimIP, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((SimPort >> 8) % 256);
|
|
bytes[i++] = (byte)(SimPort % 256);
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
bytes[i++] = (byte)(SeedCapability.Length % 256);
|
|
bytes[i++] = (byte)((SeedCapability.Length >> 8) % 256);
|
|
Buffer.BlockCopy(SeedCapability, 0, bytes, i, SeedCapability.Length); i += SeedCapability.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class InfoBlock : PacketBlock
|
|
{
|
|
public Vector3 Position;
|
|
public Vector3 LookAt;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 24;
|
|
}
|
|
}
|
|
|
|
public InfoBlock() { }
|
|
public InfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
LookAt.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
LookAt.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length += RegionData.Length;
|
|
length += Info.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RegionDataBlock RegionData;
|
|
public InfoBlock Info;
|
|
|
|
public CrossedRegionPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CrossedRegion;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 7;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
RegionData = new RegionDataBlock();
|
|
Info = new InfoBlock();
|
|
}
|
|
|
|
public CrossedRegionPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RegionData.FromBytes(bytes, ref i);
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public CrossedRegionPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
RegionData.FromBytes(bytes, ref i);
|
|
Info.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length += RegionData.Length;
|
|
length += Info.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
RegionData.ToBytes(bytes, ref i);
|
|
Info.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ConfirmEnableSimulatorPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public ConfirmEnableSimulatorPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ConfirmEnableSimulator;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 8;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public ConfirmEnableSimulatorPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ConfirmEnableSimulatorPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectPropertiesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public UUID CreatorID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public ulong CreationDate;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public int OwnershipCost;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public byte AggregatePerms;
|
|
public byte AggregatePermTextures;
|
|
public byte AggregatePermTexturesOwner;
|
|
public uint Category;
|
|
public short InventorySerial;
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
public UUID FromTaskID;
|
|
public UUID LastOwnerID;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
public byte[] TouchName;
|
|
public byte[] SitName;
|
|
public byte[] TextureID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 179;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
if (TouchName != null) { length += TouchName.Length; }
|
|
if (SitName != null) { length += SitName.Length; }
|
|
if (TextureID != null) { length += TextureID.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
CreatorID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
CreationDate = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnershipCost = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
AggregatePerms = (byte)bytes[i++];
|
|
AggregatePermTextures = (byte)bytes[i++];
|
|
AggregatePermTexturesOwner = (byte)bytes[i++];
|
|
Category = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
InventorySerial = (short)(bytes[i++] + (bytes[i++] << 8));
|
|
ItemID.FromBytes(bytes, i); i += 16;
|
|
FolderID.FromBytes(bytes, i); i += 16;
|
|
FromTaskID.FromBytes(bytes, i); i += 16;
|
|
LastOwnerID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
length = bytes[i++];
|
|
TouchName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TouchName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
SitName = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, SitName, 0, length); i += length;
|
|
length = bytes[i++];
|
|
TextureID = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TextureID, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
CreatorID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UInt64ToBytes(CreationDate, bytes, i); i += 8;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
Utils.IntToBytes(OwnershipCost, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = AggregatePerms;
|
|
bytes[i++] = AggregatePermTextures;
|
|
bytes[i++] = AggregatePermTexturesOwner;
|
|
Utils.UIntToBytes(Category, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(InventorySerial % 256);
|
|
bytes[i++] = (byte)((InventorySerial >> 8) % 256);
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
FolderID.ToBytes(bytes, i); i += 16;
|
|
FromTaskID.ToBytes(bytes, i); i += 16;
|
|
LastOwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
bytes[i++] = (byte)TouchName.Length;
|
|
Buffer.BlockCopy(TouchName, 0, bytes, i, TouchName.Length); i += TouchName.Length;
|
|
bytes[i++] = (byte)SitName.Length;
|
|
Buffer.BlockCopy(SitName, 0, bytes, i, SitName.Length); i += SitName.Length;
|
|
bytes[i++] = (byte)TextureID.Length;
|
|
Buffer.BlockCopy(TextureID, 0, bytes, i, TextureID.Length); i += TextureID.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 9;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectPropertiesPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectProperties;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 9;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectPropertiesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectPropertiesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 8;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectPropertiesFamilyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint RequestFlags;
|
|
public UUID ObjectID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public uint BaseMask;
|
|
public uint OwnerMask;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
public int OwnershipCost;
|
|
public byte SaleType;
|
|
public int SalePrice;
|
|
public uint Category;
|
|
public UUID LastOwnerID;
|
|
public byte[] Name;
|
|
public byte[] Description;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 103;
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Description != null) { length += Description.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
RequestFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
BaseMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EveryoneMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
NextOwnerMask = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnershipCost = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SaleType = (byte)bytes[i++];
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Category = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LastOwnerID.FromBytes(bytes, i); i += 16;
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Description, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(RequestFlags, bytes, i); i += 4;
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(BaseMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(OwnerMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(GroupMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(EveryoneMask, bytes, i); i += 4;
|
|
Utils.UIntToBytes(NextOwnerMask, bytes, i); i += 4;
|
|
Utils.IntToBytes(OwnershipCost, bytes, i); i += 4;
|
|
bytes[i++] = SaleType;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Category, bytes, i); i += 4;
|
|
LastOwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Description.Length;
|
|
Buffer.BlockCopy(Description, 0, bytes, i, Description.Length); i += Description.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += ObjectData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ObjectDataBlock ObjectData;
|
|
|
|
public ObjectPropertiesFamilyPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ObjectPropertiesFamily;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 10;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
ObjectData = new ObjectDataBlock();
|
|
}
|
|
|
|
public ObjectPropertiesFamilyPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ObjectPropertiesFamilyPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ObjectData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += ObjectData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ObjectData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelPropertiesRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int SequenceID;
|
|
public float West;
|
|
public float South;
|
|
public float East;
|
|
public float North;
|
|
public bool SnapSelection;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 21;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
SequenceID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
West = Utils.BytesToFloat(bytes, i); i += 4;
|
|
South = Utils.BytesToFloat(bytes, i); i += 4;
|
|
East = Utils.BytesToFloat(bytes, i); i += 4;
|
|
North = Utils.BytesToFloat(bytes, i); i += 4;
|
|
SnapSelection = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(SequenceID, bytes, i); i += 4;
|
|
Utils.FloatToBytes(West, bytes, i); i += 4;
|
|
Utils.FloatToBytes(South, bytes, i); i += 4;
|
|
Utils.FloatToBytes(East, bytes, i); i += 4;
|
|
Utils.FloatToBytes(North, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((SnapSelection) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public ParcelDataBlock ParcelData;
|
|
|
|
public ParcelPropertiesRequestPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelPropertiesRequest;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 11;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
ParcelData = new ParcelDataBlock();
|
|
}
|
|
|
|
public ParcelPropertiesRequestPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelPropertiesRequestPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length += ParcelData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AttachedSoundPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlockBlock : PacketBlock
|
|
{
|
|
public UUID SoundID;
|
|
public UUID ObjectID;
|
|
public UUID OwnerID;
|
|
public float Gain;
|
|
public byte Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 53;
|
|
}
|
|
}
|
|
|
|
public DataBlockBlock() { }
|
|
public DataBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
SoundID.FromBytes(bytes, i); i += 16;
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
Gain = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Flags = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
SoundID.ToBytes(bytes, i); i += 16;
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
Utils.FloatToBytes(Gain, bytes, i); i += 4;
|
|
bytes[i++] = Flags;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += DataBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlockBlock DataBlock;
|
|
|
|
public AttachedSoundPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AttachedSound;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 13;
|
|
Header.Reliable = true;
|
|
DataBlock = new DataBlockBlock();
|
|
}
|
|
|
|
public AttachedSoundPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AttachedSoundPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += DataBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
DataBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AttachedSoundGainChangePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlockBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public float Gain;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public DataBlockBlock() { }
|
|
public DataBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
Gain = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
Utils.FloatToBytes(Gain, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += DataBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlockBlock DataBlock;
|
|
|
|
public AttachedSoundGainChangePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AttachedSoundGainChange;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 14;
|
|
Header.Reliable = true;
|
|
DataBlock = new DataBlockBlock();
|
|
}
|
|
|
|
public AttachedSoundGainChangePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AttachedSoundGainChangePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += DataBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
DataBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PreloadSoundPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class DataBlockBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public UUID OwnerID;
|
|
public UUID SoundID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 48;
|
|
}
|
|
}
|
|
|
|
public DataBlockBlock() { }
|
|
public DataBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
SoundID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
SoundID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 9;
|
|
for (int j = 0; j < DataBlock.Length; j++)
|
|
length += DataBlock[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlockBlock[] DataBlock;
|
|
|
|
public PreloadSoundPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.PreloadSound;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 15;
|
|
Header.Reliable = true;
|
|
DataBlock = null;
|
|
}
|
|
|
|
public PreloadSoundPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(DataBlock == null || DataBlock.Length != -1) {
|
|
DataBlock = new DataBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ DataBlock[j] = new DataBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ DataBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public PreloadSoundPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(DataBlock == null || DataBlock.Length != count) {
|
|
DataBlock = new DataBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ DataBlock[j] = new DataBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ DataBlock[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length++;
|
|
for (int j = 0; j < DataBlock.Length; j++) { length += DataBlock[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)DataBlock.Length;
|
|
for (int j = 0; j < DataBlock.Length; j++) { DataBlock[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 8;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int DataBlockStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int DataBlockCount = 0;
|
|
|
|
i = DataBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < DataBlock.Length) {
|
|
int blockLength = DataBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == DataBlockStart) {
|
|
variableLength += blockLength;
|
|
++DataBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)DataBlockCount;
|
|
for (i = DataBlockStart; i < DataBlockStart + DataBlockCount; i++) { DataBlock[i].ToBytes(packet, ref length); }
|
|
DataBlockStart += DataBlockCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
DataBlockStart < DataBlock.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ViewerEffectPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EffectBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public UUID AgentID;
|
|
public byte Type;
|
|
public float Duration;
|
|
public byte[] Color;
|
|
public byte[] TypeData;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 42;
|
|
if (TypeData != null) { length += TypeData.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public EffectBlock() { }
|
|
public EffectBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
Type = (byte)bytes[i++];
|
|
Duration = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Color = new byte[4];
|
|
Buffer.BlockCopy(bytes, i, Color, 0, 4); i += 4;
|
|
length = bytes[i++];
|
|
TypeData = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TypeData, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = Type;
|
|
Utils.FloatToBytes(Duration, bytes, i); i += 4;
|
|
Buffer.BlockCopy(Color, 0, bytes, i, 4);i += 4;
|
|
bytes[i++] = (byte)TypeData.Length;
|
|
Buffer.BlockCopy(TypeData, 0, bytes, i, TypeData.Length); i += TypeData.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 9;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < Effect.Length; j++)
|
|
length += Effect[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public EffectBlock[] Effect;
|
|
|
|
public ViewerEffectPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ViewerEffect;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Medium;
|
|
Header.ID = 17;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
Effect = null;
|
|
}
|
|
|
|
public ViewerEffectPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Effect == null || Effect.Length != -1) {
|
|
Effect = new EffectBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Effect[j] = new EffectBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Effect[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ViewerEffectPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(Effect == null || Effect.Length != count) {
|
|
Effect = new EffectBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ Effect[j] = new EffectBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ Effect[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < Effect.Length; j++) { length += Effect[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)Effect.Length;
|
|
for (int j = 0; j < Effect.Length; j++) { Effect[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 8;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int EffectStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int EffectCount = 0;
|
|
|
|
i = EffectStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Effect.Length) {
|
|
int blockLength = Effect[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == EffectStart) {
|
|
variableLength += blockLength;
|
|
++EffectCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)EffectCount;
|
|
for (i = EffectStart; i < EffectStart + EffectCount; i++) { Effect[i].ToBytes(packet, ref length); }
|
|
EffectStart += EffectCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
EffectStart < Effect.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StartPingCheckPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PingIDBlock : PacketBlock
|
|
{
|
|
public byte PingID;
|
|
public uint OldestUnacked;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 5;
|
|
}
|
|
}
|
|
|
|
public PingIDBlock() { }
|
|
public PingIDBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
PingID = (byte)bytes[i++];
|
|
OldestUnacked = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = PingID;
|
|
Utils.UIntToBytes(OldestUnacked, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += PingID.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public PingIDBlock PingID;
|
|
|
|
public StartPingCheckPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.StartPingCheck;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 1;
|
|
Header.Reliable = true;
|
|
PingID = new PingIDBlock();
|
|
}
|
|
|
|
public StartPingCheckPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
PingID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public StartPingCheckPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
PingID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += PingID.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
PingID.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += PingID.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
PingID.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CompletePingCheckPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PingIDBlock : PacketBlock
|
|
{
|
|
public byte PingID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public PingIDBlock() { }
|
|
public PingIDBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
PingID = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = PingID;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += PingID.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public PingIDBlock PingID;
|
|
|
|
public CompletePingCheckPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CompletePingCheck;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 2;
|
|
Header.Reliable = true;
|
|
PingID = new PingIDBlock();
|
|
}
|
|
|
|
public CompletePingCheckPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
PingID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public CompletePingCheckPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
PingID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += PingID.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
PingID.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += PingID.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
PingID.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentUpdatePacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public Quaternion BodyRotation;
|
|
public Quaternion HeadRotation;
|
|
public byte State;
|
|
public Vector3 CameraCenter;
|
|
public Vector3 CameraAtAxis;
|
|
public Vector3 CameraLeftAxis;
|
|
public Vector3 CameraUpAxis;
|
|
public float Far;
|
|
public uint ControlFlags;
|
|
public byte Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 114;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
BodyRotation.FromBytes(bytes, i, true); i += 12;
|
|
HeadRotation.FromBytes(bytes, i, true); i += 12;
|
|
State = (byte)bytes[i++];
|
|
CameraCenter.FromBytes(bytes, i); i += 12;
|
|
CameraAtAxis.FromBytes(bytes, i); i += 12;
|
|
CameraLeftAxis.FromBytes(bytes, i); i += 12;
|
|
CameraUpAxis.FromBytes(bytes, i); i += 12;
|
|
Far = Utils.BytesToFloat(bytes, i); i += 4;
|
|
ControlFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Flags = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
BodyRotation.ToBytes(bytes, i); i += 12;
|
|
HeadRotation.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = State;
|
|
CameraCenter.ToBytes(bytes, i); i += 12;
|
|
CameraAtAxis.ToBytes(bytes, i); i += 12;
|
|
CameraLeftAxis.ToBytes(bytes, i); i += 12;
|
|
CameraUpAxis.ToBytes(bytes, i); i += 12;
|
|
Utils.FloatToBytes(Far, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ControlFlags, bytes, i); i += 4;
|
|
bytes[i++] = Flags;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public AgentUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 4;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public AgentUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentAnimationPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AnimationListBlock : PacketBlock
|
|
{
|
|
public UUID AnimID;
|
|
public bool StartAnim;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
public AnimationListBlock() { }
|
|
public AnimationListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AnimID.FromBytes(bytes, i); i += 16;
|
|
StartAnim = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AnimID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((StartAnim) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PhysicalAvatarEventListBlock : PacketBlock
|
|
{
|
|
public byte[] TypeData;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (TypeData != null) { length += TypeData.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public PhysicalAvatarEventListBlock() { }
|
|
public PhysicalAvatarEventListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
TypeData = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TypeData, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)TypeData.Length;
|
|
Buffer.BlockCopy(TypeData, 0, bytes, i, TypeData.Length); i += TypeData.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 9;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < AnimationList.Length; j++)
|
|
length += AnimationList[j].Length;
|
|
for (int j = 0; j < PhysicalAvatarEventList.Length; j++)
|
|
length += PhysicalAvatarEventList[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public AnimationListBlock[] AnimationList;
|
|
public PhysicalAvatarEventListBlock[] PhysicalAvatarEventList;
|
|
|
|
public AgentAnimationPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AgentAnimation;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 5;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
AnimationList = null;
|
|
PhysicalAvatarEventList = null;
|
|
}
|
|
|
|
public AgentAnimationPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(AnimationList == null || AnimationList.Length != -1) {
|
|
AnimationList = new AnimationListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AnimationList[j] = new AnimationListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AnimationList[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(PhysicalAvatarEventList == null || PhysicalAvatarEventList.Length != -1) {
|
|
PhysicalAvatarEventList = new PhysicalAvatarEventListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ PhysicalAvatarEventList[j] = new PhysicalAvatarEventListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ PhysicalAvatarEventList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AgentAnimationPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(AnimationList == null || AnimationList.Length != count) {
|
|
AnimationList = new AnimationListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AnimationList[j] = new AnimationListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AnimationList[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(PhysicalAvatarEventList == null || PhysicalAvatarEventList.Length != count) {
|
|
PhysicalAvatarEventList = new PhysicalAvatarEventListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ PhysicalAvatarEventList[j] = new PhysicalAvatarEventListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ PhysicalAvatarEventList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < AnimationList.Length; j++) { length += AnimationList[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < PhysicalAvatarEventList.Length; j++) { length += PhysicalAvatarEventList[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AnimationList.Length;
|
|
for (int j = 0; j < AnimationList.Length; j++) { AnimationList[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)PhysicalAvatarEventList.Length;
|
|
for (int j = 0; j < PhysicalAvatarEventList.Length; j++) { PhysicalAvatarEventList[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int AnimationListStart = 0;
|
|
int PhysicalAvatarEventListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int AnimationListCount = 0;
|
|
int PhysicalAvatarEventListCount = 0;
|
|
|
|
i = AnimationListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AnimationList.Length) {
|
|
int blockLength = AnimationList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AnimationListStart) {
|
|
variableLength += blockLength;
|
|
++AnimationListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = PhysicalAvatarEventListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < PhysicalAvatarEventList.Length) {
|
|
int blockLength = PhysicalAvatarEventList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == PhysicalAvatarEventListStart) {
|
|
variableLength += blockLength;
|
|
++PhysicalAvatarEventListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)AnimationListCount;
|
|
for (i = AnimationListStart; i < AnimationListStart + AnimationListCount; i++) { AnimationList[i].ToBytes(packet, ref length); }
|
|
AnimationListStart += AnimationListCount;
|
|
|
|
packet[length++] = (byte)PhysicalAvatarEventListCount;
|
|
for (i = PhysicalAvatarEventListStart; i < PhysicalAvatarEventListStart + PhysicalAvatarEventListCount; i++) { PhysicalAvatarEventList[i].ToBytes(packet, ref length); }
|
|
PhysicalAvatarEventListStart += PhysicalAvatarEventListCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
AnimationListStart < AnimationList.Length ||
|
|
PhysicalAvatarEventListStart < PhysicalAvatarEventList.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < AnimationList.Length; j++) { length += AnimationList[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < PhysicalAvatarEventList.Length; j++) { length += PhysicalAvatarEventList[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AnimationList.Length;
|
|
for (int j = 0; j < AnimationList.Length; j++) { AnimationList[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)PhysicalAvatarEventList.Length;
|
|
for (int j = 0; j < PhysicalAvatarEventList.Length; j++) { PhysicalAvatarEventList[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
System.Collections.Generic.List<int> retSizes = new System.Collections.Generic.List<int>();
|
|
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 2;
|
|
|
|
int AnimationListStart = 0;
|
|
int PhysicalAvatarEventListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int AnimationListCount = 0;
|
|
int PhysicalAvatarEventListCount = 0;
|
|
|
|
i = AnimationListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AnimationList.Length)
|
|
{
|
|
int blockLength = AnimationList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++AnimationListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = PhysicalAvatarEventListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < PhysicalAvatarEventList.Length)
|
|
{
|
|
int blockLength = PhysicalAvatarEventList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++PhysicalAvatarEventListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = pool.LeaseBytes(fixedLength + variableLength + acksLength);
|
|
int packetSize = fixedLength + variableLength + acksLength;
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)AnimationListCount;
|
|
for (i = AnimationListStart; i < AnimationListStart + AnimationListCount; i++) { AnimationList[i].ToBytes(packet, ref length); }
|
|
AnimationListStart += AnimationListCount;
|
|
|
|
packet[length++] = (byte)PhysicalAvatarEventListCount;
|
|
for (i = PhysicalAvatarEventListStart; i < PhysicalAvatarEventListStart + PhysicalAvatarEventListCount; i++) { PhysicalAvatarEventList[i].ToBytes(packet, ref length); }
|
|
PhysicalAvatarEventListStart += PhysicalAvatarEventListCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
retSizes.Add(packetSize);
|
|
} while (
|
|
AnimationListStart < AnimationList.Length ||
|
|
PhysicalAvatarEventListStart < PhysicalAvatarEventList.Length);
|
|
|
|
sizes = retSizes.ToArray();
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentRequestSitPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TargetObjectBlock : PacketBlock
|
|
{
|
|
public UUID TargetID;
|
|
public Vector3 Offset;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 28;
|
|
}
|
|
}
|
|
|
|
public TargetObjectBlock() { }
|
|
public TargetObjectBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
TargetID.FromBytes(bytes, i); i += 16;
|
|
Offset.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TargetID.ToBytes(bytes, i); i += 16;
|
|
Offset.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
length += TargetObject.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public TargetObjectBlock TargetObject;
|
|
|
|
public AgentRequestSitPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentRequestSit;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 6;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
TargetObject = new TargetObjectBlock();
|
|
}
|
|
|
|
public AgentRequestSitPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TargetObject.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentRequestSitPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
TargetObject.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
length += TargetObject.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TargetObject.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
length += TargetObject.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
TargetObject.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentSitPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public AgentSitPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AgentSit;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 7;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public AgentSitPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AgentSitPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestImagePacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestImageBlock : PacketBlock
|
|
{
|
|
public UUID Image;
|
|
public sbyte DiscardLevel;
|
|
public float DownloadPriority;
|
|
public uint Packet;
|
|
public byte Type;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 26;
|
|
}
|
|
}
|
|
|
|
public RequestImageBlock() { }
|
|
public RequestImageBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Image.FromBytes(bytes, i); i += 16;
|
|
DiscardLevel = (sbyte)bytes[i++];
|
|
DownloadPriority = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Packet = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Type = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Image.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)DiscardLevel;
|
|
Utils.FloatToBytes(DownloadPriority, bytes, i); i += 4;
|
|
Utils.UIntToBytes(Packet, bytes, i); i += 4;
|
|
bytes[i++] = Type;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < RequestImage.Length; j++)
|
|
length += RequestImage[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RequestImageBlock[] RequestImage;
|
|
|
|
public RequestImagePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.RequestImage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 8;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
RequestImage = null;
|
|
}
|
|
|
|
public RequestImagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RequestImage == null || RequestImage.Length != -1) {
|
|
RequestImage = new RequestImageBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RequestImage[j] = new RequestImageBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RequestImage[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public RequestImagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(RequestImage == null || RequestImage.Length != count) {
|
|
RequestImage = new RequestImageBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ RequestImage[j] = new RequestImageBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ RequestImage[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < RequestImage.Length; j++) { length += RequestImage[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)RequestImage.Length;
|
|
for (int j = 0; j < RequestImage.Length; j++) { RequestImage[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int RequestImageStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int RequestImageCount = 0;
|
|
|
|
i = RequestImageStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < RequestImage.Length) {
|
|
int blockLength = RequestImage[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == RequestImageStart) {
|
|
variableLength += blockLength;
|
|
++RequestImageCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)RequestImageCount;
|
|
for (i = RequestImageStart; i < RequestImageStart + RequestImageCount; i++) { RequestImage[i].ToBytes(packet, ref length); }
|
|
RequestImageStart += RequestImageCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
RequestImageStart < RequestImage.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < RequestImage.Length; j++) { length += RequestImage[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)RequestImage.Length;
|
|
for (int j = 0; j < RequestImage.Length; j++) { RequestImage[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
System.Collections.Generic.List<int> retSizes = new System.Collections.Generic.List<int>();
|
|
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int RequestImageStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int RequestImageCount = 0;
|
|
|
|
i = RequestImageStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < RequestImage.Length)
|
|
{
|
|
int blockLength = RequestImage[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++RequestImageCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = pool.LeaseBytes(fixedLength + variableLength + acksLength);
|
|
int packetSize = fixedLength + variableLength + acksLength;
|
|
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)RequestImageCount;
|
|
for (i = RequestImageStart; i < RequestImageStart + RequestImageCount; i++) { RequestImage[i].ToBytes(packet, ref length); }
|
|
RequestImageStart += RequestImageCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
retSizes.Add(packetSize);
|
|
packets.Add(packet);
|
|
} while (
|
|
RequestImageStart < RequestImage.Length);
|
|
|
|
sizes = retSizes.ToArray();
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImageDataPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImageIDBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public byte Codec;
|
|
public uint Size;
|
|
public ushort Packets;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 23;
|
|
}
|
|
}
|
|
|
|
public ImageIDBlock() { }
|
|
public ImageIDBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
Codec = (byte)bytes[i++];
|
|
Size = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Packets = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = Codec;
|
|
Utils.UIntToBytes(Size, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(Packets % 256);
|
|
bytes[i++] = (byte)((Packets >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImageDataBlock : PacketBlock
|
|
{
|
|
public byte[] Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (Data != null) { length += Data.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ImageDataBlock() { }
|
|
public ImageDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(Data.Length % 256);
|
|
bytes[i++] = (byte)((Data.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += ImageID.Length;
|
|
length += ImageData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ImageIDBlock ImageID;
|
|
public ImageDataBlock ImageData;
|
|
|
|
public ImageDataPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ImageData;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 9;
|
|
Header.Reliable = true;
|
|
ImageID = new ImageIDBlock();
|
|
ImageData = new ImageDataBlock();
|
|
}
|
|
|
|
public ImageDataPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ImageID.FromBytes(bytes, ref i);
|
|
ImageData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ImageDataPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ImageID.FromBytes(bytes, ref i);
|
|
ImageData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += ImageID.Length;
|
|
length += ImageData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ImageID.ToBytes(bytes, ref i);
|
|
ImageData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += ImageID.Length;
|
|
length += ImageData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ImageID.ToBytes(bytes, ref i);
|
|
ImageData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImagePacketPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImageIDBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public ushort Packet;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 18;
|
|
}
|
|
}
|
|
|
|
public ImageIDBlock() { }
|
|
public ImageIDBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
Packet = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)(Packet % 256);
|
|
bytes[i++] = (byte)((Packet >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImageDataBlock : PacketBlock
|
|
{
|
|
public byte[] Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (Data != null) { length += Data.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ImageDataBlock() { }
|
|
public ImageDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(Data.Length % 256);
|
|
bytes[i++] = (byte)((Data.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += ImageID.Length;
|
|
length += ImageData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ImageIDBlock ImageID;
|
|
public ImageDataBlock ImageData;
|
|
|
|
public ImagePacketPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ImagePacket;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 10;
|
|
Header.Reliable = true;
|
|
ImageID = new ImageIDBlock();
|
|
ImageData = new ImageDataBlock();
|
|
}
|
|
|
|
public ImagePacketPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ImageID.FromBytes(bytes, ref i);
|
|
ImageData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ImagePacketPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ImageID.FromBytes(bytes, ref i);
|
|
ImageData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += ImageID.Length;
|
|
length += ImageData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ImageID.ToBytes(bytes, ref i);
|
|
ImageData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += ImageID.Length;
|
|
length += ImageData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ImageID.ToBytes(bytes, ref i);
|
|
ImageData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LayerDataPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LayerIDBlock : PacketBlock
|
|
{
|
|
public byte Type;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public LayerIDBlock() { }
|
|
public LayerIDBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Type = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = Type;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LayerDataBlock : PacketBlock
|
|
{
|
|
public byte[] Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (Data != null) { length += Data.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public LayerDataBlock() { }
|
|
public LayerDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(Data.Length % 256);
|
|
bytes[i++] = (byte)((Data.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += LayerID.Length;
|
|
length += LayerData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public LayerIDBlock LayerID;
|
|
public LayerDataBlock LayerData;
|
|
|
|
public LayerDataPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.LayerData;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 11;
|
|
Header.Reliable = true;
|
|
LayerID = new LayerIDBlock();
|
|
LayerData = new LayerDataBlock();
|
|
}
|
|
|
|
public LayerDataPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
LayerID.FromBytes(bytes, ref i);
|
|
LayerData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public LayerDataPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
LayerID.FromBytes(bytes, ref i);
|
|
LayerData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += LayerID.Length;
|
|
length += LayerData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
LayerID.ToBytes(bytes, ref i);
|
|
LayerData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += LayerID.Length;
|
|
length += LayerData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
LayerID.ToBytes(bytes, ref i);
|
|
LayerData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectUpdatePacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionDataBlock : PacketBlock
|
|
{
|
|
public ulong RegionHandle;
|
|
public ushort TimeDilation;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 10;
|
|
}
|
|
}
|
|
|
|
public RegionDataBlock() { }
|
|
public RegionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
TimeDilation = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
bytes[i++] = (byte)(TimeDilation % 256);
|
|
bytes[i++] = (byte)((TimeDilation >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ID;
|
|
public byte State;
|
|
public UUID FullID;
|
|
public uint CRC;
|
|
public byte PCode;
|
|
public byte Material;
|
|
public byte ClickAction;
|
|
public Vector3 Scale;
|
|
public byte[] ObjectData;
|
|
public uint ParentID;
|
|
public uint UpdateFlags;
|
|
public byte PathCurve;
|
|
public byte ProfileCurve;
|
|
public ushort PathBegin;
|
|
public ushort PathEnd;
|
|
public byte PathScaleX;
|
|
public byte PathScaleY;
|
|
public byte PathShearX;
|
|
public byte PathShearY;
|
|
public sbyte PathTwist;
|
|
public sbyte PathTwistBegin;
|
|
public sbyte PathRadiusOffset;
|
|
public sbyte PathTaperX;
|
|
public sbyte PathTaperY;
|
|
public byte PathRevolutions;
|
|
public sbyte PathSkew;
|
|
public ushort ProfileBegin;
|
|
public ushort ProfileEnd;
|
|
public ushort ProfileHollow;
|
|
public byte[] TextureEntry;
|
|
public byte[] TextureAnim;
|
|
public byte[] NameValue;
|
|
public byte[] Data;
|
|
public byte[] Text;
|
|
public byte[] TextColor;
|
|
public byte[] MediaURL;
|
|
public byte[] PSBlock;
|
|
public byte[] ExtraParams;
|
|
public UUID Sound;
|
|
public UUID OwnerID;
|
|
public float Gain;
|
|
public byte Flags;
|
|
public float Radius;
|
|
public byte JointType;
|
|
public Vector3 JointPivot;
|
|
public Vector3 JointAxisOrAnchor;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 153;
|
|
if (ObjectData != null) { length += (byte)ObjectData.Length; }
|
|
if (TextureEntry != null) { length += Math.Min(TextureEntry.Length, 65535); }
|
|
if (TextureAnim != null) { length += (byte)TextureAnim.Length; }
|
|
if (NameValue != null) { length += Math.Min(NameValue.Length, 65535); }
|
|
if (Data != null) { length += Math.Min(Data.Length, 65535); }
|
|
if (Text != null) { length += (byte)Text.Length; }
|
|
if (MediaURL != null) { length += (byte)MediaURL.Length; }
|
|
if (PSBlock != null) { length += (byte)PSBlock.Length; }
|
|
if (ExtraParams != null) { length += (byte)ExtraParams.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
ID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
State = (byte)bytes[i++];
|
|
FullID.FromBytes(bytes, i); i += 16;
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PCode = (byte)bytes[i++];
|
|
Material = (byte)bytes[i++];
|
|
ClickAction = (byte)bytes[i++];
|
|
Scale.FromBytes(bytes, i); i += 12;
|
|
length = bytes[i++];
|
|
ObjectData = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ObjectData, 0, length); i += length;
|
|
ParentID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
UpdateFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PathCurve = (byte)bytes[i++];
|
|
ProfileCurve = (byte)bytes[i++];
|
|
PathBegin = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
PathEnd = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
PathScaleX = (byte)bytes[i++];
|
|
PathScaleY = (byte)bytes[i++];
|
|
PathShearX = (byte)bytes[i++];
|
|
PathShearY = (byte)bytes[i++];
|
|
PathTwist = (sbyte)bytes[i++];
|
|
PathTwistBegin = (sbyte)bytes[i++];
|
|
PathRadiusOffset = (sbyte)bytes[i++];
|
|
PathTaperX = (sbyte)bytes[i++];
|
|
PathTaperY = (sbyte)bytes[i++];
|
|
PathRevolutions = (byte)bytes[i++];
|
|
PathSkew = (sbyte)bytes[i++];
|
|
ProfileBegin = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
ProfileEnd = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
ProfileHollow = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
TextureEntry = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TextureEntry, 0, length); i += length;
|
|
length = bytes[i++];
|
|
TextureAnim = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TextureAnim, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
NameValue = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, NameValue, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Text = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Text, 0, length); i += length;
|
|
TextColor = new byte[4];
|
|
Buffer.BlockCopy(bytes, i, TextColor, 0, 4); i += 4;
|
|
length = bytes[i++];
|
|
MediaURL = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MediaURL, 0, length); i += length;
|
|
length = bytes[i++];
|
|
PSBlock = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, PSBlock, 0, length); i += length;
|
|
length = bytes[i++];
|
|
ExtraParams = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, ExtraParams, 0, length); i += length;
|
|
Sound.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
Gain = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Flags = (byte)bytes[i++];
|
|
Radius = Utils.BytesToFloat(bytes, i); i += 4;
|
|
JointType = (byte)bytes[i++];
|
|
JointPivot.FromBytes(bytes, i); i += 12;
|
|
JointAxisOrAnchor.FromBytes(bytes, i); i += 12;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ID, bytes, i); i += 4;
|
|
bytes[i++] = State;
|
|
FullID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
bytes[i++] = PCode;
|
|
bytes[i++] = Material;
|
|
bytes[i++] = ClickAction;
|
|
Scale.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
Buffer.BlockCopy(ObjectData, 0, bytes, i, (byte)ObjectData.Length); i += (byte)ObjectData.Length;
|
|
Utils.UIntToBytes(ParentID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(UpdateFlags, bytes, i); i += 4;
|
|
bytes[i++] = PathCurve;
|
|
bytes[i++] = ProfileCurve;
|
|
bytes[i++] = (byte)(PathBegin % 256);
|
|
bytes[i++] = (byte)((PathBegin >> 8) % 256);
|
|
bytes[i++] = (byte)(PathEnd % 256);
|
|
bytes[i++] = (byte)((PathEnd >> 8) % 256);
|
|
bytes[i++] = PathScaleX;
|
|
bytes[i++] = PathScaleY;
|
|
bytes[i++] = PathShearX;
|
|
bytes[i++] = PathShearY;
|
|
bytes[i++] = (byte)PathTwist;
|
|
bytes[i++] = (byte)PathTwistBegin;
|
|
bytes[i++] = (byte)PathRadiusOffset;
|
|
bytes[i++] = (byte)PathTaperX;
|
|
bytes[i++] = (byte)PathTaperY;
|
|
bytes[i++] = PathRevolutions;
|
|
bytes[i++] = (byte)PathSkew;
|
|
bytes[i++] = (byte)(ProfileBegin % 256);
|
|
bytes[i++] = (byte)((ProfileBegin >> 8) % 256);
|
|
bytes[i++] = (byte)(ProfileEnd % 256);
|
|
bytes[i++] = (byte)((ProfileEnd >> 8) % 256);
|
|
bytes[i++] = (byte)(ProfileHollow % 256);
|
|
bytes[i++] = (byte)((ProfileHollow >> 8) % 256);
|
|
|
|
int truncTextureEntryLen = Math.Min(TextureEntry.Length, 65535);
|
|
bytes[i++] = (byte)(truncTextureEntryLen % 256);
|
|
bytes[i++] = (byte)((truncTextureEntryLen >> 8) % 256);
|
|
Buffer.BlockCopy(TextureEntry, 0, bytes, i, truncTextureEntryLen); i += truncTextureEntryLen;
|
|
|
|
byte truncTextureAnimLen = (byte)TextureAnim.Length;
|
|
bytes[i++] = truncTextureAnimLen;
|
|
Buffer.BlockCopy(TextureAnim, 0, bytes, i, truncTextureAnimLen); i += truncTextureAnimLen;
|
|
|
|
int truncNameValueLen = Math.Min(NameValue.Length, 65535);
|
|
bytes[i++] = (byte)(truncNameValueLen % 256);
|
|
bytes[i++] = (byte)((truncNameValueLen >> 8) % 256);
|
|
Buffer.BlockCopy(NameValue, 0, bytes, i, truncNameValueLen); i += truncNameValueLen;
|
|
|
|
int truncDataLen = Math.Min(Data.Length, 65535);
|
|
bytes[i++] = (byte)(truncDataLen % 256);
|
|
bytes[i++] = (byte)((truncDataLen >> 8) % 256);
|
|
Buffer.BlockCopy(Data, 0, bytes, i, truncDataLen); i += truncDataLen;
|
|
|
|
byte truncTextLen = (byte)Text.Length;
|
|
bytes[i++] = truncTextLen;
|
|
Buffer.BlockCopy(Text, 0, bytes, i, truncTextLen); i += truncTextLen;
|
|
|
|
Buffer.BlockCopy(TextColor, 0, bytes, i, 4);i += 4;
|
|
|
|
byte truncMediaUrlLen = (byte)MediaURL.Length;
|
|
bytes[i++] = truncMediaUrlLen;
|
|
Buffer.BlockCopy(MediaURL, 0, bytes, i, truncMediaUrlLen); i += truncMediaUrlLen;
|
|
|
|
byte truncPsBlockLen = (byte)PSBlock.Length;
|
|
bytes[i++] = truncPsBlockLen;
|
|
Buffer.BlockCopy(PSBlock, 0, bytes, i, truncPsBlockLen); i += truncPsBlockLen;
|
|
|
|
byte truncExtraParamsLen = (byte)ExtraParams.Length;
|
|
bytes[i++] = truncExtraParamsLen;
|
|
Buffer.BlockCopy(ExtraParams, 0, bytes, i, truncExtraParamsLen); i += truncExtraParamsLen;
|
|
|
|
Sound.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
Utils.FloatToBytes(Gain, bytes, i); i += 4;
|
|
bytes[i++] = Flags;
|
|
Utils.FloatToBytes(Radius, bytes, i); i += 4;
|
|
bytes[i++] = JointType;
|
|
JointPivot.ToBytes(bytes, i); i += 12;
|
|
JointAxisOrAnchor.ToBytes(bytes, i); i += 12;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += RegionData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RegionDataBlock RegionData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 12;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
RegionData = new RegionDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
RegionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
RegionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += RegionData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RegionData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += RegionData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
RegionData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += RegionData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RegionData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
System.Collections.Generic.List<int> retSizes = new System.Collections.Generic.List<int>();
|
|
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += RegionData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
RegionData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length)
|
|
{
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart)
|
|
{
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
int packetSize = fixedLength + variableLength + acksLength;
|
|
byte[] packet = pool.LeaseBytes(packetSize);
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
retSizes.Add(packetSize);
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
sizes = retSizes.ToArray();
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectUpdateCompressedPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionDataBlock : PacketBlock
|
|
{
|
|
public ulong RegionHandle;
|
|
public ushort TimeDilation;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 10;
|
|
}
|
|
}
|
|
|
|
public RegionDataBlock() { }
|
|
public RegionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
TimeDilation = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
bytes[i++] = (byte)(TimeDilation % 256);
|
|
bytes[i++] = (byte)((TimeDilation >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint UpdateFlags;
|
|
public byte[] Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 6;
|
|
if (Data != null) { length += Data.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
UpdateFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(UpdateFlags, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(Data.Length % 256);
|
|
bytes[i++] = (byte)((Data.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += RegionData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RegionDataBlock RegionData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectUpdateCompressedPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectUpdateCompressed;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 13;
|
|
Header.Reliable = true;
|
|
RegionData = new RegionDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectUpdateCompressedPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
RegionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectUpdateCompressedPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
RegionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += RegionData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RegionData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += RegionData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
RegionData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += RegionData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RegionData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
System.Collections.Generic.List<int> retSizes = new System.Collections.Generic.List<int>();
|
|
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += RegionData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
RegionData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length)
|
|
{
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
int packetSize = fixedLength + variableLength + acksLength;
|
|
byte[] packet = pool.LeaseBytes(packetSize);
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
retSizes.Add(packetSize);
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
sizes = retSizes.ToArray();
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectUpdateCachedPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionDataBlock : PacketBlock
|
|
{
|
|
public ulong RegionHandle;
|
|
public ushort TimeDilation;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 10;
|
|
}
|
|
}
|
|
|
|
public RegionDataBlock() { }
|
|
public RegionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
TimeDilation = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
bytes[i++] = (byte)(TimeDilation % 256);
|
|
bytes[i++] = (byte)((TimeDilation >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ID;
|
|
public uint CRC;
|
|
public uint UpdateFlags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
CRC = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
UpdateFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ID, bytes, i); i += 4;
|
|
Utils.UIntToBytes(CRC, bytes, i); i += 4;
|
|
Utils.UIntToBytes(UpdateFlags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += RegionData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RegionDataBlock RegionData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ObjectUpdateCachedPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectUpdateCached;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 14;
|
|
Header.Reliable = true;
|
|
RegionData = new RegionDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ObjectUpdateCachedPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
RegionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectUpdateCachedPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
RegionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += RegionData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RegionData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += RegionData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
RegionData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += RegionData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RegionData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
System.Collections.Generic.List<int> retSizes = new System.Collections.Generic.List<int>();
|
|
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += RegionData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
RegionData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length)
|
|
{
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
int packetSize = fixedLength + variableLength + acksLength;
|
|
byte[] packet = pool.LeaseBytes(packetSize);
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
retSizes.Add(packetSize);
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
sizes = retSizes.ToArray();
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImprovedTerseObjectUpdatePacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionDataBlock : PacketBlock
|
|
{
|
|
public ulong RegionHandle;
|
|
public ushort TimeDilation;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 10;
|
|
}
|
|
}
|
|
|
|
public RegionDataBlock() { }
|
|
public RegionDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
TimeDilation = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
bytes[i++] = (byte)(TimeDilation % 256);
|
|
bytes[i++] = (byte)((TimeDilation >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public byte[] Data;
|
|
public byte[] TextureEntry;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 3;
|
|
if (Data != null) { length += Data.Length; }
|
|
if (TextureEntry != null) { length += TextureEntry.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
TextureEntry = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TextureEntry, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)Data.Length;
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
bytes[i++] = (byte)(TextureEntry.Length % 256);
|
|
bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256);
|
|
Buffer.BlockCopy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += RegionData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RegionDataBlock RegionData;
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public ImprovedTerseObjectUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ImprovedTerseObjectUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 15;
|
|
Header.Reliable = true;
|
|
RegionData = new RegionDataBlock();
|
|
ObjectData = null;
|
|
}
|
|
|
|
public ImprovedTerseObjectUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
RegionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ImprovedTerseObjectUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
RegionData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += RegionData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RegionData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += RegionData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
RegionData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += RegionData.Length;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
RegionData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
System.Collections.Generic.List<int> retSizes = new System.Collections.Generic.List<int>();
|
|
|
|
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += RegionData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
RegionData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length)
|
|
{
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
int packetSize = fixedLength + variableLength + acksLength;
|
|
byte[] packet = pool.LeaseBytes(packetSize);
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
retSizes.Add(packetSize);
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
sizes = retSizes.ToArray();
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class KillObjectPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public ObjectDataBlock() { }
|
|
public ObjectDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(ID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
for (int j = 0; j < ObjectData.Length; j++)
|
|
length += ObjectData[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ObjectDataBlock[] ObjectData;
|
|
|
|
public KillObjectPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.KillObject;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 16;
|
|
Header.Reliable = true;
|
|
ObjectData = null;
|
|
}
|
|
|
|
public KillObjectPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != -1) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public KillObjectPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
int count = (int)bytes[i++];
|
|
if(ObjectData == null || ObjectData.Length != count) {
|
|
ObjectData = new ObjectDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ ObjectData[j] = new ObjectDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ ObjectData[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length) {
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == ObjectDataStart) {
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length++;
|
|
for (int j = 0; j < ObjectData.Length; j++) { length += ObjectData[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)ObjectData.Length;
|
|
for (int j = 0; j < ObjectData.Length; j++) { ObjectData[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
System.Collections.Generic.List<int> retSizes = new System.Collections.Generic.List<int>();
|
|
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ObjectDataStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int ObjectDataCount = 0;
|
|
|
|
i = ObjectDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < ObjectData.Length)
|
|
{
|
|
int blockLength = ObjectData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++ObjectDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
int packetSize = fixedLength + variableLength + acksLength;
|
|
byte[] packet = pool.LeaseBytes(packetSize);
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)ObjectDataCount;
|
|
for (i = ObjectDataStart; i < ObjectDataStart + ObjectDataCount; i++) { ObjectData[i].ToBytes(packet, ref length); }
|
|
ObjectDataStart += ObjectDataCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
retSizes.Add(packetSize);
|
|
packets.Add(packet);
|
|
} while (
|
|
ObjectDataStart < ObjectData.Length);
|
|
|
|
sizes = retSizes.ToArray();
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransferPacketPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransferDataBlock : PacketBlock
|
|
{
|
|
public UUID TransferID;
|
|
public int ChannelType;
|
|
public int Packet;
|
|
public int Status;
|
|
public byte[] Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 30;
|
|
if (Data != null) { length += Data.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public TransferDataBlock() { }
|
|
public TransferDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
TransferID.FromBytes(bytes, i); i += 16;
|
|
ChannelType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Packet = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Status = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
TransferID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(ChannelType, bytes, i); i += 4;
|
|
Utils.IntToBytes(Packet, bytes, i); i += 4;
|
|
Utils.IntToBytes(Status, bytes, i); i += 4;
|
|
bytes[i++] = (byte)(Data.Length % 256);
|
|
bytes[i++] = (byte)((Data.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += TransferData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TransferDataBlock TransferData;
|
|
|
|
public TransferPacketPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.TransferPacket;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 17;
|
|
Header.Reliable = true;
|
|
TransferData = new TransferDataBlock();
|
|
}
|
|
|
|
public TransferPacketPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
TransferData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public TransferPacketPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
TransferData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += TransferData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TransferData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += TransferData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
TransferData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SendXferPacketPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class XferIDBlock : PacketBlock
|
|
{
|
|
public ulong ID;
|
|
public uint Packet;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public XferIDBlock() { }
|
|
public XferIDBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
Packet = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(ID, bytes, i); i += 8;
|
|
Utils.UIntToBytes(Packet, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataPacketBlock : PacketBlock
|
|
{
|
|
public byte[] Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (Data != null) { length += Data.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataPacketBlock() { }
|
|
public DataPacketBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(Data.Length % 256);
|
|
bytes[i++] = (byte)((Data.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += XferID.Length;
|
|
length += DataPacket.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public XferIDBlock XferID;
|
|
public DataPacketBlock DataPacket;
|
|
|
|
public SendXferPacketPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SendXferPacket;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 18;
|
|
Header.Reliable = true;
|
|
XferID = new XferIDBlock();
|
|
DataPacket = new DataPacketBlock();
|
|
}
|
|
|
|
public SendXferPacketPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
XferID.FromBytes(bytes, ref i);
|
|
DataPacket.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SendXferPacketPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
XferID.FromBytes(bytes, ref i);
|
|
DataPacket.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += XferID.Length;
|
|
length += DataPacket.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
XferID.ToBytes(bytes, ref i);
|
|
DataPacket.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += XferID.Length;
|
|
length += DataPacket.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
XferID.ToBytes(bytes, ref i);
|
|
DataPacket.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ConfirmXferPacketPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class XferIDBlock : PacketBlock
|
|
{
|
|
public ulong ID;
|
|
public uint Packet;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public XferIDBlock() { }
|
|
public XferIDBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
Packet = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(ID, bytes, i); i += 8;
|
|
Utils.UIntToBytes(Packet, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += XferID.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public XferIDBlock XferID;
|
|
|
|
public ConfirmXferPacketPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ConfirmXferPacket;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 19;
|
|
Header.Reliable = true;
|
|
XferID = new XferIDBlock();
|
|
}
|
|
|
|
public ConfirmXferPacketPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
XferID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ConfirmXferPacketPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
XferID.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += XferID.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
XferID.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += XferID.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
XferID.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarAnimationPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SenderBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public SenderBlock() { }
|
|
public SenderBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AnimationListBlock : PacketBlock
|
|
{
|
|
public UUID AnimID;
|
|
public int AnimSequenceID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public AnimationListBlock() { }
|
|
public AnimationListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AnimID.FromBytes(bytes, i); i += 16;
|
|
AnimSequenceID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AnimID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(AnimSequenceID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AnimationSourceListBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public AnimationSourceListBlock() { }
|
|
public AnimationSourceListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PhysicalAvatarEventListBlock : PacketBlock
|
|
{
|
|
public byte[] TypeData;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (TypeData != null) { length += TypeData.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public PhysicalAvatarEventListBlock() { }
|
|
public PhysicalAvatarEventListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
TypeData = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, TypeData, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)TypeData.Length;
|
|
Buffer.BlockCopy(TypeData, 0, bytes, i, TypeData.Length); i += TypeData.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Sender.Length;
|
|
for (int j = 0; j < AnimationList.Length; j++)
|
|
length += AnimationList[j].Length;
|
|
for (int j = 0; j < AnimationSourceList.Length; j++)
|
|
length += AnimationSourceList[j].Length;
|
|
for (int j = 0; j < PhysicalAvatarEventList.Length; j++)
|
|
length += PhysicalAvatarEventList[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public SenderBlock Sender;
|
|
public AnimationListBlock[] AnimationList;
|
|
public AnimationSourceListBlock[] AnimationSourceList;
|
|
public PhysicalAvatarEventListBlock[] PhysicalAvatarEventList;
|
|
|
|
public AvatarAnimationPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.AvatarAnimation;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 20;
|
|
Header.Reliable = true;
|
|
Sender = new SenderBlock();
|
|
AnimationList = null;
|
|
AnimationSourceList = null;
|
|
PhysicalAvatarEventList = null;
|
|
}
|
|
|
|
public AvatarAnimationPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Sender.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(AnimationList == null || AnimationList.Length != -1) {
|
|
AnimationList = new AnimationListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AnimationList[j] = new AnimationListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AnimationList[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AnimationSourceList == null || AnimationSourceList.Length != -1) {
|
|
AnimationSourceList = new AnimationSourceListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AnimationSourceList[j] = new AnimationSourceListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AnimationSourceList[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(PhysicalAvatarEventList == null || PhysicalAvatarEventList.Length != -1) {
|
|
PhysicalAvatarEventList = new PhysicalAvatarEventListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ PhysicalAvatarEventList[j] = new PhysicalAvatarEventListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ PhysicalAvatarEventList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public AvatarAnimationPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Sender.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(AnimationList == null || AnimationList.Length != count) {
|
|
AnimationList = new AnimationListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AnimationList[j] = new AnimationListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AnimationList[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AnimationSourceList == null || AnimationSourceList.Length != count) {
|
|
AnimationSourceList = new AnimationSourceListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AnimationSourceList[j] = new AnimationSourceListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AnimationSourceList[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(PhysicalAvatarEventList == null || PhysicalAvatarEventList.Length != count) {
|
|
PhysicalAvatarEventList = new PhysicalAvatarEventListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ PhysicalAvatarEventList[j] = new PhysicalAvatarEventListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ PhysicalAvatarEventList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += Sender.Length;
|
|
length++;
|
|
for (int j = 0; j < AnimationList.Length; j++) { length += AnimationList[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AnimationSourceList.Length; j++) { length += AnimationSourceList[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < PhysicalAvatarEventList.Length; j++) { length += PhysicalAvatarEventList[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Sender.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AnimationList.Length;
|
|
for (int j = 0; j < AnimationList.Length; j++) { AnimationList[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AnimationSourceList.Length;
|
|
for (int j = 0; j < AnimationSourceList.Length; j++) { AnimationSourceList[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)PhysicalAvatarEventList.Length;
|
|
for (int j = 0; j < PhysicalAvatarEventList.Length; j++) { PhysicalAvatarEventList[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += Sender.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
Sender.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 3;
|
|
|
|
int AnimationListStart = 0;
|
|
int AnimationSourceListStart = 0;
|
|
int PhysicalAvatarEventListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int AnimationListCount = 0;
|
|
int AnimationSourceListCount = 0;
|
|
int PhysicalAvatarEventListCount = 0;
|
|
|
|
i = AnimationListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AnimationList.Length) {
|
|
int blockLength = AnimationList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AnimationListStart) {
|
|
variableLength += blockLength;
|
|
++AnimationListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AnimationSourceListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AnimationSourceList.Length) {
|
|
int blockLength = AnimationSourceList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AnimationSourceListStart) {
|
|
variableLength += blockLength;
|
|
++AnimationSourceListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = PhysicalAvatarEventListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < PhysicalAvatarEventList.Length) {
|
|
int blockLength = PhysicalAvatarEventList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == PhysicalAvatarEventListStart) {
|
|
variableLength += blockLength;
|
|
++PhysicalAvatarEventListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)AnimationListCount;
|
|
for (i = AnimationListStart; i < AnimationListStart + AnimationListCount; i++) { AnimationList[i].ToBytes(packet, ref length); }
|
|
AnimationListStart += AnimationListCount;
|
|
|
|
packet[length++] = (byte)AnimationSourceListCount;
|
|
for (i = AnimationSourceListStart; i < AnimationSourceListStart + AnimationSourceListCount; i++) { AnimationSourceList[i].ToBytes(packet, ref length); }
|
|
AnimationSourceListStart += AnimationSourceListCount;
|
|
|
|
packet[length++] = (byte)PhysicalAvatarEventListCount;
|
|
for (i = PhysicalAvatarEventListStart; i < PhysicalAvatarEventListStart + PhysicalAvatarEventListCount; i++) { PhysicalAvatarEventList[i].ToBytes(packet, ref length); }
|
|
PhysicalAvatarEventListStart += PhysicalAvatarEventListCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
AnimationListStart < AnimationList.Length ||
|
|
AnimationSourceListStart < AnimationSourceList.Length ||
|
|
PhysicalAvatarEventListStart < PhysicalAvatarEventList.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += Sender.Length;
|
|
length++;
|
|
for (int j = 0; j < AnimationList.Length; j++) { length += AnimationList[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AnimationSourceList.Length; j++) { length += AnimationSourceList[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < PhysicalAvatarEventList.Length; j++) { length += PhysicalAvatarEventList[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Sender.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AnimationList.Length;
|
|
for (int j = 0; j < AnimationList.Length; j++) { AnimationList[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AnimationSourceList.Length;
|
|
for (int j = 0; j < AnimationSourceList.Length; j++) { AnimationSourceList[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)PhysicalAvatarEventList.Length;
|
|
for (int j = 0; j < PhysicalAvatarEventList.Length; j++) { PhysicalAvatarEventList[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
System.Collections.Generic.List<int> retSizes = new System.Collections.Generic.List<int>();
|
|
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += Sender.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
Sender.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 3;
|
|
|
|
int AnimationListStart = 0;
|
|
int AnimationSourceListStart = 0;
|
|
int PhysicalAvatarEventListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int AnimationListCount = 0;
|
|
int AnimationSourceListCount = 0;
|
|
int PhysicalAvatarEventListCount = 0;
|
|
|
|
i = AnimationListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AnimationList.Length)
|
|
{
|
|
int blockLength = AnimationList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++AnimationListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AnimationSourceListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AnimationSourceList.Length)
|
|
{
|
|
int blockLength = AnimationSourceList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++AnimationSourceListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = PhysicalAvatarEventListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < PhysicalAvatarEventList.Length)
|
|
{
|
|
int blockLength = PhysicalAvatarEventList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++PhysicalAvatarEventListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
int packetSize = fixedLength + variableLength + acksLength;
|
|
byte[] packet = pool.LeaseBytes(packetSize);
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)AnimationListCount;
|
|
for (i = AnimationListStart; i < AnimationListStart + AnimationListCount; i++) { AnimationList[i].ToBytes(packet, ref length); }
|
|
AnimationListStart += AnimationListCount;
|
|
|
|
packet[length++] = (byte)AnimationSourceListCount;
|
|
for (i = AnimationSourceListStart; i < AnimationSourceListStart + AnimationSourceListCount; i++) { AnimationSourceList[i].ToBytes(packet, ref length); }
|
|
AnimationSourceListStart += AnimationSourceListCount;
|
|
|
|
packet[length++] = (byte)PhysicalAvatarEventListCount;
|
|
for (i = PhysicalAvatarEventListStart; i < PhysicalAvatarEventListStart + PhysicalAvatarEventListCount; i++) { PhysicalAvatarEventList[i].ToBytes(packet, ref length); }
|
|
PhysicalAvatarEventListStart += PhysicalAvatarEventListCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
retSizes.Add(packetSize);
|
|
packets.Add(packet);
|
|
} while (
|
|
AnimationListStart < AnimationList.Length ||
|
|
AnimationSourceListStart < AnimationSourceList.Length ||
|
|
PhysicalAvatarEventListStart < PhysicalAvatarEventList.Length);
|
|
|
|
sizes = retSizes.ToArray();
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarSitResponsePacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SitObjectBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public SitObjectBlock() { }
|
|
public SitObjectBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SitTransformBlock : PacketBlock
|
|
{
|
|
public bool AutoPilot;
|
|
public Vector3 SitPosition;
|
|
public Quaternion SitRotation;
|
|
public Vector3 CameraEyeOffset;
|
|
public Vector3 CameraAtOffset;
|
|
public bool ForceMouselook;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 50;
|
|
}
|
|
}
|
|
|
|
public SitTransformBlock() { }
|
|
public SitTransformBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AutoPilot = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
SitPosition.FromBytes(bytes, i); i += 12;
|
|
SitRotation.FromBytes(bytes, i, true); i += 12;
|
|
CameraEyeOffset.FromBytes(bytes, i); i += 12;
|
|
CameraAtOffset.FromBytes(bytes, i); i += 12;
|
|
ForceMouselook = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((AutoPilot) ? 1 : 0);
|
|
SitPosition.ToBytes(bytes, i); i += 12;
|
|
SitRotation.ToBytes(bytes, i); i += 12;
|
|
CameraEyeOffset.ToBytes(bytes, i); i += 12;
|
|
CameraAtOffset.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = (byte)((ForceMouselook) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += SitObject.Length;
|
|
length += SitTransform.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public SitObjectBlock SitObject;
|
|
public SitTransformBlock SitTransform;
|
|
|
|
public AvatarSitResponsePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.AvatarSitResponse;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 21;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
SitObject = new SitObjectBlock();
|
|
SitTransform = new SitTransformBlock();
|
|
}
|
|
|
|
public AvatarSitResponsePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
SitObject.FromBytes(bytes, ref i);
|
|
SitTransform.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public AvatarSitResponsePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
SitObject.FromBytes(bytes, ref i);
|
|
SitTransform.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += SitObject.Length;
|
|
length += SitTransform.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
SitObject.ToBytes(bytes, ref i);
|
|
SitTransform.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += SitObject.Length;
|
|
length += SitTransform.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
SitObject.ToBytes(bytes, ref i);
|
|
SitTransform.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CameraConstraintPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CameraCollidePlaneBlock : PacketBlock
|
|
{
|
|
public Vector4 Plane;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public CameraCollidePlaneBlock() { }
|
|
public CameraCollidePlaneBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Plane.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Plane.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += CameraCollidePlane.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public CameraCollidePlaneBlock CameraCollidePlane;
|
|
|
|
public CameraConstraintPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CameraConstraint;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 22;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
CameraCollidePlane = new CameraCollidePlaneBlock();
|
|
}
|
|
|
|
public CameraConstraintPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
CameraCollidePlane.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public CameraConstraintPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
CameraCollidePlane.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += CameraCollidePlane.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
CameraCollidePlane.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += CameraCollidePlane.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
CameraCollidePlane.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelPropertiesPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int RequestResult;
|
|
public int SequenceID;
|
|
public bool SnapSelection;
|
|
public int SelfCount;
|
|
public int OtherCount;
|
|
public int PublicCount;
|
|
public int LocalID;
|
|
public UUID OwnerID;
|
|
public bool IsGroupOwned;
|
|
public uint AuctionID;
|
|
public int ClaimDate;
|
|
public int ClaimPrice;
|
|
public int RentPrice;
|
|
public Vector3 AABBMin;
|
|
public Vector3 AABBMax;
|
|
public byte[] Bitmap;
|
|
public int Area;
|
|
public byte Status;
|
|
public int SimWideMaxPrims;
|
|
public int SimWideTotalPrims;
|
|
public int MaxPrims;
|
|
public int TotalPrims;
|
|
public int OwnerPrims;
|
|
public int GroupPrims;
|
|
public int OtherPrims;
|
|
public int SelectedPrims;
|
|
public float ParcelPrimBonus;
|
|
public int OtherCleanTime;
|
|
public uint ParcelFlags;
|
|
public int SalePrice;
|
|
public byte[] Name;
|
|
public byte[] Desc;
|
|
public byte[] MusicURL;
|
|
public byte[] MediaURL;
|
|
public UUID MediaID;
|
|
public byte MediaAutoScale;
|
|
public UUID GroupID;
|
|
public int PassPrice;
|
|
public float PassHours;
|
|
public byte Category;
|
|
public UUID AuthBuyerID;
|
|
public UUID SnapshotID;
|
|
public Vector3 UserLocation;
|
|
public Vector3 UserLookAt;
|
|
public byte LandingType;
|
|
public bool RegionPushOverride;
|
|
public bool RegionDenyAnonymous;
|
|
public bool RegionDenyIdentified;
|
|
public bool RegionDenyTransacted;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 244;
|
|
if (Bitmap != null) { length += Bitmap.Length; }
|
|
if (Name != null) { length += Name.Length; }
|
|
if (Desc != null) { length += Desc.Length; }
|
|
if (MusicURL != null) { length += MusicURL.Length; }
|
|
if (MediaURL != null) { length += MediaURL.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public ParcelDataBlock() { }
|
|
public ParcelDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
RequestResult = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SequenceID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SnapSelection = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
SelfCount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OtherCount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PublicCount = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
LocalID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
IsGroupOwned = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
AuctionID = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ClaimDate = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ClaimPrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RentPrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
AABBMin.FromBytes(bytes, i); i += 12;
|
|
AABBMax.FromBytes(bytes, i); i += 12;
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Bitmap = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Bitmap, 0, length); i += length;
|
|
Area = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
Status = (byte)bytes[i++];
|
|
SimWideMaxPrims = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SimWideTotalPrims = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
MaxPrims = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
TotalPrims = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OwnerPrims = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
GroupPrims = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
OtherPrims = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SelectedPrims = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ParcelPrimBonus = Utils.BytesToFloat(bytes, i); i += 4;
|
|
OtherCleanTime = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
ParcelFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
SalePrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
length = bytes[i++];
|
|
Name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Name, 0, length); i += length;
|
|
length = bytes[i++];
|
|
Desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Desc, 0, length); i += length;
|
|
length = bytes[i++];
|
|
MusicURL = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MusicURL, 0, length); i += length;
|
|
length = bytes[i++];
|
|
MediaURL = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, MediaURL, 0, length); i += length;
|
|
MediaID.FromBytes(bytes, i); i += 16;
|
|
MediaAutoScale = (byte)bytes[i++];
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
PassPrice = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
PassHours = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Category = (byte)bytes[i++];
|
|
AuthBuyerID.FromBytes(bytes, i); i += 16;
|
|
SnapshotID.FromBytes(bytes, i); i += 16;
|
|
UserLocation.FromBytes(bytes, i); i += 12;
|
|
UserLookAt.FromBytes(bytes, i); i += 12;
|
|
LandingType = (byte)bytes[i++];
|
|
RegionPushOverride = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
RegionDenyAnonymous = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
RegionDenyIdentified = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
RegionDenyTransacted = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(RequestResult, bytes, i); i += 4;
|
|
Utils.IntToBytes(SequenceID, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((SnapSelection) ? 1 : 0);
|
|
Utils.IntToBytes(SelfCount, bytes, i); i += 4;
|
|
Utils.IntToBytes(OtherCount, bytes, i); i += 4;
|
|
Utils.IntToBytes(PublicCount, bytes, i); i += 4;
|
|
Utils.IntToBytes(LocalID, bytes, i); i += 4;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsGroupOwned) ? 1 : 0);
|
|
Utils.UIntToBytes(AuctionID, bytes, i); i += 4;
|
|
Utils.IntToBytes(ClaimDate, bytes, i); i += 4;
|
|
Utils.IntToBytes(ClaimPrice, bytes, i); i += 4;
|
|
Utils.IntToBytes(RentPrice, bytes, i); i += 4;
|
|
AABBMin.ToBytes(bytes, i); i += 12;
|
|
AABBMax.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = (byte)(Bitmap.Length % 256);
|
|
bytes[i++] = (byte)((Bitmap.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Bitmap, 0, bytes, i, Bitmap.Length); i += Bitmap.Length;
|
|
Utils.IntToBytes(Area, bytes, i); i += 4;
|
|
bytes[i++] = Status;
|
|
Utils.IntToBytes(SimWideMaxPrims, bytes, i); i += 4;
|
|
Utils.IntToBytes(SimWideTotalPrims, bytes, i); i += 4;
|
|
Utils.IntToBytes(MaxPrims, bytes, i); i += 4;
|
|
Utils.IntToBytes(TotalPrims, bytes, i); i += 4;
|
|
Utils.IntToBytes(OwnerPrims, bytes, i); i += 4;
|
|
Utils.IntToBytes(GroupPrims, bytes, i); i += 4;
|
|
Utils.IntToBytes(OtherPrims, bytes, i); i += 4;
|
|
Utils.IntToBytes(SelectedPrims, bytes, i); i += 4;
|
|
Utils.FloatToBytes(ParcelPrimBonus, bytes, i); i += 4;
|
|
Utils.IntToBytes(OtherCleanTime, bytes, i); i += 4;
|
|
Utils.UIntToBytes(ParcelFlags, bytes, i); i += 4;
|
|
Utils.IntToBytes(SalePrice, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Name.Length;
|
|
Buffer.BlockCopy(Name, 0, bytes, i, Name.Length); i += Name.Length;
|
|
bytes[i++] = (byte)Desc.Length;
|
|
Buffer.BlockCopy(Desc, 0, bytes, i, Desc.Length); i += Desc.Length;
|
|
bytes[i++] = (byte)MusicURL.Length;
|
|
Buffer.BlockCopy(MusicURL, 0, bytes, i, MusicURL.Length); i += MusicURL.Length;
|
|
bytes[i++] = (byte)MediaURL.Length;
|
|
Buffer.BlockCopy(MediaURL, 0, bytes, i, MediaURL.Length); i += MediaURL.Length;
|
|
MediaID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = MediaAutoScale;
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(PassPrice, bytes, i); i += 4;
|
|
Utils.FloatToBytes(PassHours, bytes, i); i += 4;
|
|
bytes[i++] = Category;
|
|
AuthBuyerID.ToBytes(bytes, i); i += 16;
|
|
SnapshotID.ToBytes(bytes, i); i += 16;
|
|
UserLocation.ToBytes(bytes, i); i += 12;
|
|
UserLookAt.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = LandingType;
|
|
bytes[i++] = (byte)((RegionPushOverride) ? 1 : 0);
|
|
bytes[i++] = (byte)((RegionDenyAnonymous) ? 1 : 0);
|
|
bytes[i++] = (byte)((RegionDenyIdentified) ? 1 : 0);
|
|
bytes[i++] = (byte)((RegionDenyTransacted) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgeVerificationBlockBlock : PacketBlock
|
|
{
|
|
public bool RegionDenyAgeUnverified;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public AgeVerificationBlockBlock() { }
|
|
public AgeVerificationBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionDenyAgeUnverified = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((RegionDenyAgeUnverified) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RegionAllowAccessBlockBlock : PacketBlock
|
|
{
|
|
public bool RegionAllowAccessOverride;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public RegionAllowAccessBlockBlock() { }
|
|
public RegionAllowAccessBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionAllowAccessOverride = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)((RegionAllowAccessOverride) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelEnvironmentBlockBlock : PacketBlock
|
|
{
|
|
public int ParcelEnvironmentVersion;
|
|
public bool RegionAllowEnvironmentOverride;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 5;
|
|
}
|
|
}
|
|
|
|
public ParcelEnvironmentBlockBlock() { }
|
|
public ParcelEnvironmentBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ParcelEnvironmentVersion = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
RegionAllowEnvironmentOverride = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.IntToBytes(ParcelEnvironmentVersion, bytes, i); i += 4;
|
|
bytes[i++] = (byte)((RegionAllowEnvironmentOverride) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += ParcelData.Length;
|
|
length += AgeVerificationBlock.Length;
|
|
length += RegionAllowAccessBlock.Length;
|
|
length += ParcelEnvironmentBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ParcelDataBlock ParcelData;
|
|
public AgeVerificationBlockBlock AgeVerificationBlock;
|
|
public RegionAllowAccessBlockBlock RegionAllowAccessBlock;
|
|
public ParcelEnvironmentBlockBlock ParcelEnvironmentBlock;
|
|
|
|
public ParcelPropertiesPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ParcelProperties;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 23;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
ParcelData = new ParcelDataBlock();
|
|
AgeVerificationBlock = new AgeVerificationBlockBlock();
|
|
RegionAllowAccessBlock = new RegionAllowAccessBlockBlock();
|
|
ParcelEnvironmentBlock = new ParcelEnvironmentBlockBlock();
|
|
}
|
|
|
|
public ParcelPropertiesPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
AgeVerificationBlock.FromBytes(bytes, ref i);
|
|
RegionAllowAccessBlock.FromBytes(bytes, ref i);
|
|
ParcelEnvironmentBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ParcelPropertiesPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
ParcelData.FromBytes(bytes, ref i);
|
|
AgeVerificationBlock.FromBytes(bytes, ref i);
|
|
RegionAllowAccessBlock.FromBytes(bytes, ref i);
|
|
ParcelEnvironmentBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += ParcelData.Length;
|
|
length += AgeVerificationBlock.Length;
|
|
length += RegionAllowAccessBlock.Length;
|
|
length += ParcelEnvironmentBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
AgeVerificationBlock.ToBytes(bytes, ref i);
|
|
RegionAllowAccessBlock.ToBytes(bytes, ref i);
|
|
ParcelEnvironmentBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += ParcelData.Length;
|
|
length += AgeVerificationBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
ParcelData.ToBytes(bytes, ref i);
|
|
AgeVerificationBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChildAgentUpdatePacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public ulong RegionHandle;
|
|
public uint ViewerCircuitCode;
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public Vector3 AgentPos;
|
|
public Vector3 AgentVel;
|
|
public Vector3 Center;
|
|
public Vector3 Size;
|
|
public Vector3 AtAxis;
|
|
public Vector3 LeftAxis;
|
|
public Vector3 UpAxis;
|
|
public bool ChangedGrid;
|
|
public float Far;
|
|
public float Aspect;
|
|
public byte[] Throttles;
|
|
public uint LocomotionState;
|
|
public Quaternion HeadRotation;
|
|
public Quaternion BodyRotation;
|
|
public uint ControlFlags;
|
|
public float EnergyLevel;
|
|
public byte GodLevel;
|
|
public bool AlwaysRun;
|
|
public UUID PreyAgent;
|
|
public byte AgentAccess;
|
|
public byte[] AgentTextures;
|
|
public UUID ActiveGroupID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 211;
|
|
if (Throttles != null) { length += Throttles.Length; }
|
|
if (AgentTextures != null) { length += AgentTextures.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
ViewerCircuitCode = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
AgentPos.FromBytes(bytes, i); i += 12;
|
|
AgentVel.FromBytes(bytes, i); i += 12;
|
|
Center.FromBytes(bytes, i); i += 12;
|
|
Size.FromBytes(bytes, i); i += 12;
|
|
AtAxis.FromBytes(bytes, i); i += 12;
|
|
LeftAxis.FromBytes(bytes, i); i += 12;
|
|
UpAxis.FromBytes(bytes, i); i += 12;
|
|
ChangedGrid = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
Far = Utils.BytesToFloat(bytes, i); i += 4;
|
|
Aspect = Utils.BytesToFloat(bytes, i); i += 4;
|
|
length = bytes[i++];
|
|
Throttles = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Throttles, 0, length); i += length;
|
|
LocomotionState = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
HeadRotation.FromBytes(bytes, i, true); i += 12;
|
|
BodyRotation.FromBytes(bytes, i, true); i += 12;
|
|
ControlFlags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
EnergyLevel = Utils.BytesToFloat(bytes, i); i += 4;
|
|
GodLevel = (byte)bytes[i++];
|
|
AlwaysRun = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
PreyAgent.FromBytes(bytes, i); i += 16;
|
|
AgentAccess = (byte)bytes[i++];
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
AgentTextures = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, AgentTextures, 0, length); i += length;
|
|
ActiveGroupID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
Utils.UIntToBytes(ViewerCircuitCode, bytes, i); i += 4;
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
AgentPos.ToBytes(bytes, i); i += 12;
|
|
AgentVel.ToBytes(bytes, i); i += 12;
|
|
Center.ToBytes(bytes, i); i += 12;
|
|
Size.ToBytes(bytes, i); i += 12;
|
|
AtAxis.ToBytes(bytes, i); i += 12;
|
|
LeftAxis.ToBytes(bytes, i); i += 12;
|
|
UpAxis.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = (byte)((ChangedGrid) ? 1 : 0);
|
|
Utils.FloatToBytes(Far, bytes, i); i += 4;
|
|
Utils.FloatToBytes(Aspect, bytes, i); i += 4;
|
|
bytes[i++] = (byte)Throttles.Length;
|
|
Buffer.BlockCopy(Throttles, 0, bytes, i, Throttles.Length); i += Throttles.Length;
|
|
Utils.UIntToBytes(LocomotionState, bytes, i); i += 4;
|
|
HeadRotation.ToBytes(bytes, i); i += 12;
|
|
BodyRotation.ToBytes(bytes, i); i += 12;
|
|
Utils.UIntToBytes(ControlFlags, bytes, i); i += 4;
|
|
Utils.FloatToBytes(EnergyLevel, bytes, i); i += 4;
|
|
bytes[i++] = GodLevel;
|
|
bytes[i++] = (byte)((AlwaysRun) ? 1 : 0);
|
|
PreyAgent.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = AgentAccess;
|
|
bytes[i++] = (byte)(AgentTextures.Length % 256);
|
|
bytes[i++] = (byte)((AgentTextures.Length >> 8) % 256);
|
|
Buffer.BlockCopy(AgentTextures, 0, bytes, i, AgentTextures.Length); i += AgentTextures.Length;
|
|
ActiveGroupID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public ulong GroupPowers;
|
|
public bool AcceptNotices;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 25;
|
|
}
|
|
}
|
|
|
|
public GroupDataBlock() { }
|
|
public GroupDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
GroupPowers = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
AcceptNotices = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GroupID.ToBytes(bytes, i); i += 16;
|
|
Utils.UInt64ToBytes(GroupPowers, bytes, i); i += 8;
|
|
bytes[i++] = (byte)((AcceptNotices) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AnimationDataBlock : PacketBlock
|
|
{
|
|
public UUID Animation;
|
|
public UUID ObjectID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 32;
|
|
}
|
|
}
|
|
|
|
public AnimationDataBlock() { }
|
|
public AnimationDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Animation.FromBytes(bytes, i); i += 16;
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Animation.ToBytes(bytes, i); i += 16;
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GranterBlockBlock : PacketBlock
|
|
{
|
|
public UUID GranterID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public GranterBlockBlock() { }
|
|
public GranterBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
GranterID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
GranterID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class NVPairDataBlock : PacketBlock
|
|
{
|
|
public byte[] NVPairs;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (NVPairs != null) { length += NVPairs.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public NVPairDataBlock() { }
|
|
public NVPairDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
NVPairs = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, NVPairs, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(NVPairs.Length % 256);
|
|
bytes[i++] = (byte)((NVPairs.Length >> 8) % 256);
|
|
Buffer.BlockCopy(NVPairs, 0, bytes, i, NVPairs.Length); i += NVPairs.Length;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class VisualParamBlock : PacketBlock
|
|
{
|
|
public byte ParamValue;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public VisualParamBlock() { }
|
|
public VisualParamBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ParamValue = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = ParamValue;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentAccessBlock : PacketBlock
|
|
{
|
|
public byte AgentLegacyAccess;
|
|
public byte AgentMaxAccess;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
public AgentAccessBlock() { }
|
|
public AgentAccessBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AgentLegacyAccess = (byte)bytes[i++];
|
|
AgentMaxAccess = (byte)bytes[i++];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = AgentLegacyAccess;
|
|
bytes[i++] = AgentMaxAccess;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentInfoBlock : PacketBlock
|
|
{
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public AgentInfoBlock() { }
|
|
public AgentInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Flags = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentInventoryHostBlock : PacketBlock
|
|
{
|
|
public byte[] InventoryHost;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 1;
|
|
if (InventoryHost != null) { length += InventoryHost.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public AgentInventoryHostBlock() { }
|
|
public AgentInventoryHostBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = bytes[i++];
|
|
InventoryHost = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, InventoryHost, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)InventoryHost.Length;
|
|
Buffer.BlockCopy(InventoryHost, 0, bytes, i, InventoryHost.Length); i += InventoryHost.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 15;
|
|
length += AgentData.Length;
|
|
for (int j = 0; j < GroupData.Length; j++)
|
|
length += GroupData[j].Length;
|
|
for (int j = 0; j < AnimationData.Length; j++)
|
|
length += AnimationData[j].Length;
|
|
for (int j = 0; j < GranterBlock.Length; j++)
|
|
length += GranterBlock[j].Length;
|
|
for (int j = 0; j < NVPairData.Length; j++)
|
|
length += NVPairData[j].Length;
|
|
for (int j = 0; j < VisualParam.Length; j++)
|
|
length += VisualParam[j].Length;
|
|
for (int j = 0; j < AgentAccess.Length; j++)
|
|
length += AgentAccess[j].Length;
|
|
for (int j = 0; j < AgentInfo.Length; j++)
|
|
length += AgentInfo[j].Length;
|
|
for (int j = 0; j < AgentInventoryHost.Length; j++)
|
|
length += AgentInventoryHost[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock[] GroupData;
|
|
public AnimationDataBlock[] AnimationData;
|
|
public GranterBlockBlock[] GranterBlock;
|
|
public NVPairDataBlock[] NVPairData;
|
|
public VisualParamBlock[] VisualParam;
|
|
public AgentAccessBlock[] AgentAccess;
|
|
public AgentInfoBlock[] AgentInfo;
|
|
public AgentInventoryHostBlock[] AgentInventoryHost;
|
|
|
|
public ChildAgentUpdatePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ChildAgentUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 25;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
GroupData = null;
|
|
AnimationData = null;
|
|
GranterBlock = null;
|
|
NVPairData = null;
|
|
VisualParam = null;
|
|
AgentAccess = null;
|
|
AgentInfo = null;
|
|
AgentInventoryHost = null;
|
|
}
|
|
|
|
public ChildAgentUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(GroupData == null || GroupData.Length != -1) {
|
|
GroupData = new GroupDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ GroupData[j] = new GroupDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ GroupData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AnimationData == null || AnimationData.Length != -1) {
|
|
AnimationData = new AnimationDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AnimationData[j] = new AnimationDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AnimationData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(GranterBlock == null || GranterBlock.Length != -1) {
|
|
GranterBlock = new GranterBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ GranterBlock[j] = new GranterBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ GranterBlock[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(NVPairData == null || NVPairData.Length != -1) {
|
|
NVPairData = new NVPairDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ NVPairData[j] = new NVPairDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ NVPairData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(VisualParam == null || VisualParam.Length != -1) {
|
|
VisualParam = new VisualParamBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ VisualParam[j] = new VisualParamBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ VisualParam[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AgentAccess == null || AgentAccess.Length != -1) {
|
|
AgentAccess = new AgentAccessBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentAccess[j] = new AgentAccessBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentAccess[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AgentInfo == null || AgentInfo.Length != -1) {
|
|
AgentInfo = new AgentInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentInfo[j] = new AgentInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentInfo[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AgentInventoryHost == null || AgentInventoryHost.Length != -1) {
|
|
AgentInventoryHost = new AgentInventoryHostBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentInventoryHost[j] = new AgentInventoryHostBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentInventoryHost[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ChildAgentUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(GroupData == null || GroupData.Length != count) {
|
|
GroupData = new GroupDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ GroupData[j] = new GroupDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ GroupData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AnimationData == null || AnimationData.Length != count) {
|
|
AnimationData = new AnimationDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AnimationData[j] = new AnimationDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AnimationData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(GranterBlock == null || GranterBlock.Length != count) {
|
|
GranterBlock = new GranterBlockBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ GranterBlock[j] = new GranterBlockBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ GranterBlock[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(NVPairData == null || NVPairData.Length != count) {
|
|
NVPairData = new NVPairDataBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ NVPairData[j] = new NVPairDataBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ NVPairData[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(VisualParam == null || VisualParam.Length != count) {
|
|
VisualParam = new VisualParamBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ VisualParam[j] = new VisualParamBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ VisualParam[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AgentAccess == null || AgentAccess.Length != count) {
|
|
AgentAccess = new AgentAccessBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentAccess[j] = new AgentAccessBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentAccess[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AgentInfo == null || AgentInfo.Length != count) {
|
|
AgentInfo = new AgentInfoBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentInfo[j] = new AgentInfoBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentInfo[j].FromBytes(bytes, ref i); }
|
|
count = (int)bytes[i++];
|
|
if(AgentInventoryHost == null || AgentInventoryHost.Length != count) {
|
|
AgentInventoryHost = new AgentInventoryHostBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AgentInventoryHost[j] = new AgentInventoryHostBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AgentInventoryHost[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < GroupData.Length; j++) { length += GroupData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AnimationData.Length; j++) { length += AnimationData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < GranterBlock.Length; j++) { length += GranterBlock[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < NVPairData.Length; j++) { length += NVPairData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < VisualParam.Length; j++) { length += VisualParam[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AgentAccess.Length; j++) { length += AgentAccess[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AgentInfo.Length; j++) { length += AgentInfo[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AgentInventoryHost.Length; j++) { length += AgentInventoryHost[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)GroupData.Length;
|
|
for (int j = 0; j < GroupData.Length; j++) { GroupData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AnimationData.Length;
|
|
for (int j = 0; j < AnimationData.Length; j++) { AnimationData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)GranterBlock.Length;
|
|
for (int j = 0; j < GranterBlock.Length; j++) { GranterBlock[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)NVPairData.Length;
|
|
for (int j = 0; j < NVPairData.Length; j++) { NVPairData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)VisualParam.Length;
|
|
for (int j = 0; j < VisualParam.Length; j++) { VisualParam[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AgentAccess.Length;
|
|
for (int j = 0; j < AgentAccess.Length; j++) { AgentAccess[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AgentInfo.Length;
|
|
for (int j = 0; j < AgentInfo.Length; j++) { AgentInfo[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AgentInventoryHost.Length;
|
|
for (int j = 0; j < AgentInventoryHost.Length; j++) { AgentInventoryHost[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 8;
|
|
|
|
int GroupDataStart = 0;
|
|
int AnimationDataStart = 0;
|
|
int GranterBlockStart = 0;
|
|
int NVPairDataStart = 0;
|
|
int VisualParamStart = 0;
|
|
int AgentAccessStart = 0;
|
|
int AgentInfoStart = 0;
|
|
int AgentInventoryHostStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int GroupDataCount = 0;
|
|
int AnimationDataCount = 0;
|
|
int GranterBlockCount = 0;
|
|
int NVPairDataCount = 0;
|
|
int VisualParamCount = 0;
|
|
int AgentAccessCount = 0;
|
|
int AgentInfoCount = 0;
|
|
int AgentInventoryHostCount = 0;
|
|
|
|
i = GroupDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < GroupData.Length) {
|
|
int blockLength = GroupData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == GroupDataStart) {
|
|
variableLength += blockLength;
|
|
++GroupDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AnimationDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AnimationData.Length) {
|
|
int blockLength = AnimationData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AnimationDataStart) {
|
|
variableLength += blockLength;
|
|
++AnimationDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = GranterBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < GranterBlock.Length) {
|
|
int blockLength = GranterBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == GranterBlockStart) {
|
|
variableLength += blockLength;
|
|
++GranterBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = NVPairDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < NVPairData.Length) {
|
|
int blockLength = NVPairData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == NVPairDataStart) {
|
|
variableLength += blockLength;
|
|
++NVPairDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = VisualParamStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < VisualParam.Length) {
|
|
int blockLength = VisualParam[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == VisualParamStart) {
|
|
variableLength += blockLength;
|
|
++VisualParamCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AgentAccessStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AgentAccess.Length) {
|
|
int blockLength = AgentAccess[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AgentAccessStart) {
|
|
variableLength += blockLength;
|
|
++AgentAccessCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AgentInfoStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AgentInfo.Length) {
|
|
int blockLength = AgentInfo[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AgentInfoStart) {
|
|
variableLength += blockLength;
|
|
++AgentInfoCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AgentInventoryHostStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AgentInventoryHost.Length) {
|
|
int blockLength = AgentInventoryHost[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AgentInventoryHostStart) {
|
|
variableLength += blockLength;
|
|
++AgentInventoryHostCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)GroupDataCount;
|
|
for (i = GroupDataStart; i < GroupDataStart + GroupDataCount; i++) { GroupData[i].ToBytes(packet, ref length); }
|
|
GroupDataStart += GroupDataCount;
|
|
|
|
packet[length++] = (byte)AnimationDataCount;
|
|
for (i = AnimationDataStart; i < AnimationDataStart + AnimationDataCount; i++) { AnimationData[i].ToBytes(packet, ref length); }
|
|
AnimationDataStart += AnimationDataCount;
|
|
|
|
packet[length++] = (byte)GranterBlockCount;
|
|
for (i = GranterBlockStart; i < GranterBlockStart + GranterBlockCount; i++) { GranterBlock[i].ToBytes(packet, ref length); }
|
|
GranterBlockStart += GranterBlockCount;
|
|
|
|
packet[length++] = (byte)NVPairDataCount;
|
|
for (i = NVPairDataStart; i < NVPairDataStart + NVPairDataCount; i++) { NVPairData[i].ToBytes(packet, ref length); }
|
|
NVPairDataStart += NVPairDataCount;
|
|
|
|
packet[length++] = (byte)VisualParamCount;
|
|
for (i = VisualParamStart; i < VisualParamStart + VisualParamCount; i++) { VisualParam[i].ToBytes(packet, ref length); }
|
|
VisualParamStart += VisualParamCount;
|
|
|
|
packet[length++] = (byte)AgentAccessCount;
|
|
for (i = AgentAccessStart; i < AgentAccessStart + AgentAccessCount; i++) { AgentAccess[i].ToBytes(packet, ref length); }
|
|
AgentAccessStart += AgentAccessCount;
|
|
|
|
packet[length++] = (byte)AgentInfoCount;
|
|
for (i = AgentInfoStart; i < AgentInfoStart + AgentInfoCount; i++) { AgentInfo[i].ToBytes(packet, ref length); }
|
|
AgentInfoStart += AgentInfoCount;
|
|
|
|
packet[length++] = (byte)AgentInventoryHostCount;
|
|
for (i = AgentInventoryHostStart; i < AgentInventoryHostStart + AgentInventoryHostCount; i++) { AgentInventoryHost[i].ToBytes(packet, ref length); }
|
|
AgentInventoryHostStart += AgentInventoryHostCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
GroupDataStart < GroupData.Length ||
|
|
AnimationDataStart < AnimationData.Length ||
|
|
GranterBlockStart < GranterBlock.Length ||
|
|
NVPairDataStart < NVPairData.Length ||
|
|
VisualParamStart < VisualParam.Length ||
|
|
AgentAccessStart < AgentAccess.Length ||
|
|
AgentInfoStart < AgentInfo.Length ||
|
|
AgentInventoryHostStart < AgentInventoryHost.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
length++;
|
|
for (int j = 0; j < GroupData.Length; j++) { length += GroupData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AnimationData.Length; j++) { length += AnimationData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < GranterBlock.Length; j++) { length += GranterBlock[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < NVPairData.Length; j++) { length += NVPairData[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < VisualParam.Length; j++) { length += VisualParam[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AgentAccess.Length; j++) { length += AgentAccess[j].Length; }
|
|
length++;
|
|
for (int j = 0; j < AgentInfo.Length; j++) { length += AgentInfo[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)GroupData.Length;
|
|
for (int j = 0; j < GroupData.Length; j++) { GroupData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AnimationData.Length;
|
|
for (int j = 0; j < AnimationData.Length; j++) { AnimationData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)GranterBlock.Length;
|
|
for (int j = 0; j < GranterBlock.Length; j++) { GranterBlock[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)NVPairData.Length;
|
|
for (int j = 0; j < NVPairData.Length; j++) { NVPairData[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)VisualParam.Length;
|
|
for (int j = 0; j < VisualParam.Length; j++) { VisualParam[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AgentAccess.Length;
|
|
for (int j = 0; j < AgentAccess.Length; j++) { AgentAccess[j].ToBytes(bytes, ref i); }
|
|
bytes[i++] = (byte)AgentInfo.Length;
|
|
for (int j = 0; j < AgentInfo.Length; j++) { AgentInfo[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
System.Collections.Generic.List<int> retSizes = new System.Collections.Generic.List<int>();
|
|
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0)
|
|
{
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += AgentData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AgentData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 7;
|
|
|
|
int GroupDataStart = 0;
|
|
int AnimationDataStart = 0;
|
|
int GranterBlockStart = 0;
|
|
int NVPairDataStart = 0;
|
|
int VisualParamStart = 0;
|
|
int AgentAccessStart = 0;
|
|
int AgentInfoStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int GroupDataCount = 0;
|
|
int AnimationDataCount = 0;
|
|
int GranterBlockCount = 0;
|
|
int NVPairDataCount = 0;
|
|
int VisualParamCount = 0;
|
|
int AgentAccessCount = 0;
|
|
int AgentInfoCount = 0;
|
|
|
|
i = GroupDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < GroupData.Length)
|
|
{
|
|
int blockLength = GroupData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++GroupDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AnimationDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AnimationData.Length)
|
|
{
|
|
int blockLength = AnimationData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++AnimationDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = GranterBlockStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < GranterBlock.Length)
|
|
{
|
|
int blockLength = GranterBlock[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++GranterBlockCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = NVPairDataStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < NVPairData.Length)
|
|
{
|
|
int blockLength = NVPairData[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++NVPairDataCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = VisualParamStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < VisualParam.Length)
|
|
{
|
|
int blockLength = VisualParam[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++VisualParamCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AgentAccessStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AgentAccess.Length)
|
|
{
|
|
int blockLength = AgentAccess[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++AgentAccessCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
i = AgentInfoStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AgentInfo.Length)
|
|
{
|
|
int blockLength = AgentInfo[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU)
|
|
{
|
|
variableLength += blockLength;
|
|
++AgentInfoCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
int packetSize = fixedLength + variableLength + acksLength;
|
|
byte[] packet = pool.LeaseBytes(packetSize);
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)GroupDataCount;
|
|
for (i = GroupDataStart; i < GroupDataStart + GroupDataCount; i++) { GroupData[i].ToBytes(packet, ref length); }
|
|
GroupDataStart += GroupDataCount;
|
|
|
|
packet[length++] = (byte)AnimationDataCount;
|
|
for (i = AnimationDataStart; i < AnimationDataStart + AnimationDataCount; i++) { AnimationData[i].ToBytes(packet, ref length); }
|
|
AnimationDataStart += AnimationDataCount;
|
|
|
|
packet[length++] = (byte)GranterBlockCount;
|
|
for (i = GranterBlockStart; i < GranterBlockStart + GranterBlockCount; i++) { GranterBlock[i].ToBytes(packet, ref length); }
|
|
GranterBlockStart += GranterBlockCount;
|
|
|
|
packet[length++] = (byte)NVPairDataCount;
|
|
for (i = NVPairDataStart; i < NVPairDataStart + NVPairDataCount; i++) { NVPairData[i].ToBytes(packet, ref length); }
|
|
NVPairDataStart += NVPairDataCount;
|
|
|
|
packet[length++] = (byte)VisualParamCount;
|
|
for (i = VisualParamStart; i < VisualParamStart + VisualParamCount; i++) { VisualParam[i].ToBytes(packet, ref length); }
|
|
VisualParamStart += VisualParamCount;
|
|
|
|
packet[length++] = (byte)AgentAccessCount;
|
|
for (i = AgentAccessStart; i < AgentAccessStart + AgentAccessCount; i++) { AgentAccess[i].ToBytes(packet, ref length); }
|
|
AgentAccessStart += AgentAccessCount;
|
|
|
|
packet[length++] = (byte)AgentInfoCount;
|
|
for (i = AgentInfoStart; i < AgentInfoStart + AgentInfoCount; i++) { AgentInfo[i].ToBytes(packet, ref length); }
|
|
AgentInfoStart += AgentInfoCount;
|
|
|
|
if (acksLength > 0)
|
|
{
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
retSizes.Add(packetSize);
|
|
packets.Add(packet);
|
|
|
|
} while (
|
|
GroupDataStart < GroupData.Length ||
|
|
AnimationDataStart < AnimationData.Length ||
|
|
GranterBlockStart < GranterBlock.Length ||
|
|
NVPairDataStart < NVPairData.Length ||
|
|
VisualParamStart < VisualParam.Length ||
|
|
AgentAccessStart < AgentAccess.Length ||
|
|
AgentInfoStart < AgentInfo.Length);
|
|
|
|
sizes = retSizes.ToArray();
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChildAgentAlivePacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public ulong RegionHandle;
|
|
public uint ViewerCircuitCode;
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 44;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
ViewerCircuitCode = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
Utils.UIntToBytes(ViewerCircuitCode, bytes, i); i += 4;
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public ChildAgentAlivePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ChildAgentAlive;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 26;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public ChildAgentAlivePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ChildAgentAlivePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChildAgentPositionUpdatePacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataBlock : PacketBlock
|
|
{
|
|
public ulong RegionHandle;
|
|
public uint ViewerCircuitCode;
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public Vector3 AgentPos;
|
|
public Vector3 AgentVel;
|
|
public Vector3 Center;
|
|
public Vector3 Size;
|
|
public Vector3 AtAxis;
|
|
public Vector3 LeftAxis;
|
|
public Vector3 UpAxis;
|
|
public bool ChangedGrid;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 129;
|
|
}
|
|
}
|
|
|
|
public AgentDataBlock() { }
|
|
public AgentDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
RegionHandle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
ViewerCircuitCode = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
SessionID.FromBytes(bytes, i); i += 16;
|
|
AgentPos.FromBytes(bytes, i); i += 12;
|
|
AgentVel.FromBytes(bytes, i); i += 12;
|
|
Center.FromBytes(bytes, i); i += 12;
|
|
Size.FromBytes(bytes, i); i += 12;
|
|
AtAxis.FromBytes(bytes, i); i += 12;
|
|
LeftAxis.FromBytes(bytes, i); i += 12;
|
|
UpAxis.FromBytes(bytes, i); i += 12;
|
|
ChangedGrid = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
Utils.UIntToBytes(ViewerCircuitCode, bytes, i); i += 4;
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
AgentPos.ToBytes(bytes, i); i += 12;
|
|
AgentVel.ToBytes(bytes, i); i += 12;
|
|
Center.ToBytes(bytes, i); i += 12;
|
|
Size.ToBytes(bytes, i); i += 12;
|
|
AtAxis.ToBytes(bytes, i); i += 12;
|
|
LeftAxis.ToBytes(bytes, i); i += 12;
|
|
UpAxis.ToBytes(bytes, i); i += 12;
|
|
bytes[i++] = (byte)((ChangedGrid) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public ChildAgentPositionUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ChildAgentPositionUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 27;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
public ChildAgentPositionUpdatePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public ChildAgentPositionUpdatePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
AgentData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += AgentData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
AgentData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SoundTriggerPacket : Packet
|
|
{
|
|
public override bool UsesBufferPooling
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SoundDataBlock : PacketBlock
|
|
{
|
|
public UUID SoundID;
|
|
public UUID OwnerID;
|
|
public UUID ObjectID;
|
|
public UUID ParentID;
|
|
public ulong Handle;
|
|
public Vector3 Position;
|
|
public float Gain;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 88;
|
|
}
|
|
}
|
|
|
|
public SoundDataBlock() { }
|
|
public SoundDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
SoundID.FromBytes(bytes, i); i += 16;
|
|
OwnerID.FromBytes(bytes, i); i += 16;
|
|
ObjectID.FromBytes(bytes, i); i += 16;
|
|
ParentID.FromBytes(bytes, i); i += 16;
|
|
Handle = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + ((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + ((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + ((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));
|
|
Position.FromBytes(bytes, i); i += 12;
|
|
Gain = Utils.BytesToFloat(bytes, i); i += 4;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
SoundID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
ObjectID.ToBytes(bytes, i); i += 16;
|
|
ParentID.ToBytes(bytes, i); i += 16;
|
|
Utils.UInt64ToBytes(Handle, bytes, i); i += 8;
|
|
Position.ToBytes(bytes, i); i += 12;
|
|
Utils.FloatToBytes(Gain, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += SoundData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public SoundDataBlock SoundData;
|
|
|
|
public SoundTriggerPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.SoundTrigger;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 29;
|
|
Header.Reliable = true;
|
|
SoundData = new SoundDataBlock();
|
|
}
|
|
|
|
public SoundTriggerPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
SoundData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public SoundTriggerPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
SoundData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += SoundData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
SoundData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
|
|
public override byte[] ToBytes(Interfaces.IByteBufferPool pool, ref int size)
|
|
{
|
|
int length = 7;
|
|
length += SoundData.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = pool.LeaseBytes(length);
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
SoundData.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
|
|
size = length;
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple(Interfaces.IByteBufferPool pool, out int[] sizes)
|
|
{
|
|
sizes = new int[1];
|
|
return new byte[][] { this.ToBytes(pool, ref sizes[0]) };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectAnimationPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class SenderBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public SenderBlock() { }
|
|
public SenderBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
ID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AnimationListBlock : PacketBlock
|
|
{
|
|
public UUID AnimID;
|
|
public int AnimSequenceID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public AnimationListBlock() { }
|
|
public AnimationListBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
AnimID.FromBytes(bytes, i); i += 16;
|
|
AnimSequenceID = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
AnimID.ToBytes(bytes, i); i += 16;
|
|
Utils.IntToBytes(AnimSequenceID, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 8;
|
|
length += Sender.Length;
|
|
for (int j = 0; j < AnimationList.Length; j++)
|
|
length += AnimationList[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public SenderBlock Sender;
|
|
public AnimationListBlock[] AnimationList;
|
|
|
|
public ObjectAnimationPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.ObjectAnimation;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 30;
|
|
Header.Reliable = true;
|
|
Sender = new SenderBlock();
|
|
AnimationList = null;
|
|
}
|
|
|
|
public ObjectAnimationPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
Sender.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(AnimationList == null || AnimationList.Length != -1) {
|
|
AnimationList = new AnimationListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AnimationList[j] = new AnimationListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AnimationList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public ObjectAnimationPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
Sender.FromBytes(bytes, ref i);
|
|
int count = (int)bytes[i++];
|
|
if(AnimationList == null || AnimationList.Length != count) {
|
|
AnimationList = new AnimationListBlock[count];
|
|
for(int j = 0; j < count; j++)
|
|
{ AnimationList[j] = new AnimationListBlock(); }
|
|
}
|
|
for (int j = 0; j < count; j++)
|
|
{ AnimationList[j].FromBytes(bytes, ref i); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += Sender.Length;
|
|
length++;
|
|
for (int j = 0; j < AnimationList.Length; j++) { length += AnimationList[j].Length; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
Sender.ToBytes(bytes, ref i);
|
|
bytes[i++] = (byte)AnimationList.Length;
|
|
for (int j = 0; j < AnimationList.Length; j++) { AnimationList[j].ToBytes(bytes, ref i); }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();
|
|
int i = 0;
|
|
int fixedLength = 7;
|
|
|
|
byte[] ackBytes = null;
|
|
int acksLength = 0;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) {
|
|
Header.AppendedAcks = true;
|
|
ackBytes = new byte[Header.AckList.Length * 4 + 1];
|
|
Header.AcksToBytes(ackBytes, ref acksLength);
|
|
}
|
|
|
|
fixedLength += Sender.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
Sender.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int AnimationListStart = 0;
|
|
do
|
|
{
|
|
int variableLength = 0;
|
|
int AnimationListCount = 0;
|
|
|
|
i = AnimationListStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < AnimationList.Length) {
|
|
int blockLength = AnimationList[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU || i == AnimationListStart) {
|
|
variableLength += blockLength;
|
|
++AnimationListCount;
|
|
}
|
|
else { break; }
|
|
++i;
|
|
}
|
|
|
|
byte[] packet = new byte[fixedLength + variableLength + acksLength];
|
|
int length = fixedBytes.Length;
|
|
Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);
|
|
if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }
|
|
|
|
packet[length++] = (byte)AnimationListCount;
|
|
for (i = AnimationListStart; i < AnimationListStart + AnimationListCount; i++) { AnimationList[i].ToBytes(packet, ref length); }
|
|
AnimationListStart += AnimationListCount;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
} while (
|
|
AnimationListStart < AnimationList.Length);
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GenericStreamingMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public sealed class MethodDataBlock : PacketBlock
|
|
{
|
|
public ushort Method;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
public MethodDataBlock() { }
|
|
public MethodDataBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
Method = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(Method % 256);
|
|
bytes[i++] = (byte)((Method >> 8) % 256);
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DataBlockBlock : PacketBlock
|
|
{
|
|
public byte[] Data;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 2;
|
|
if (Data != null) { length += Data.Length; }
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public DataBlockBlock() { }
|
|
public DataBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
int length;
|
|
try
|
|
{
|
|
length = (bytes[i++] + (bytes[i++] << 8));
|
|
Data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, Data, 0, length); i += length;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
bytes[i++] = (byte)(Data.Length % 256);
|
|
bytes[i++] = (byte)((Data.Length >> 8) % 256);
|
|
Buffer.BlockCopy(Data, 0, bytes, i, Data.Length); i += Data.Length;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += MethodData.Length;
|
|
length += DataBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public MethodDataBlock MethodData;
|
|
public DataBlockBlock DataBlock;
|
|
|
|
public GenericStreamingMessagePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.GenericStreamingMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.High;
|
|
Header.ID = 31;
|
|
Header.Reliable = true;
|
|
MethodData = new MethodDataBlock();
|
|
DataBlock = new DataBlockBlock();
|
|
}
|
|
|
|
public GenericStreamingMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
MethodData.FromBytes(bytes, ref i);
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public GenericStreamingMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
MethodData.FromBytes(bytes, ref i);
|
|
DataBlock.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 7;
|
|
length += MethodData.Length;
|
|
length += DataBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }
|
|
byte[] bytes = new byte[length];
|
|
int i = 0;
|
|
Header.ToBytes(bytes, ref i);
|
|
MethodData.ToBytes(bytes, ref i);
|
|
DataBlock.ToBytes(bytes, ref i);
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
}
|