LIBOMV-576 Start of Abstracting library into two separate libraries. For now this means: There will be a new dependency for OpenMetaverse.dll named OpenMetaverseCore.dll, the new will be required for OpenMetaverse to operate properly, the inverse is not true. OpenMetaverseCore will eventually contain all packet and message related code. * Need to create a singleton logger instance (or move the current logger to Core. * Currently only Packets, Helpers and some common types have been moved to Core. * Helpers will need to be split and non-core required helpers moved back to OpenMetaverse. * Lots more work to be done here, but these changes should not break anything (yet) git-svn-id: http://libopenmetaverse.googlecode.com/svn/libopenmetaverse/trunk@3021 52acb1d6-8a22-11de-b505-999d5b087335
81982 lines
2.8 MiB
81982 lines
2.8 MiB
/*
|
|
* Copyright (c) 2008, openmetaverse.org
|
|
* 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.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,
|
|
NearestLandingRegionUpdated = 65682,
|
|
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,
|
|
KickUserAck = 65700,
|
|
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,
|
|
RequestInventoryAsset = 65818,
|
|
InventoryAssetResponse = 65819,
|
|
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,
|
|
FormFriendship = 65835,
|
|
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,
|
|
CreateTrustedCircuit = 65928,
|
|
DenyTrustedCircuit = 65929,
|
|
RequestTrustedCircuit = 65930,
|
|
RezSingleAttachmentFromInv = 65931,
|
|
RezMultipleAttachmentsFromInv = 65932,
|
|
DetachAttachmentIntoInv = 65933,
|
|
CreateNewOutfitAttachments = 65934,
|
|
UserInfoRequest = 65935,
|
|
UserInfoReply = 65936,
|
|
UpdateUserInfo = 65937,
|
|
InitiateDownload = 65939,
|
|
SystemMessage = 65940,
|
|
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,
|
|
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,
|
|
}
|
|
|
|
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 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 146: return PacketType.NearestLandingRegionUpdated;
|
|
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 164: return PacketType.KickUserAck;
|
|
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 282: return PacketType.RequestInventoryAsset;
|
|
case 283: return PacketType.InventoryAssetResponse;
|
|
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 299: return PacketType.FormFriendship;
|
|
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 392: return PacketType.CreateTrustedCircuit;
|
|
case 393: return PacketType.DenyTrustedCircuit;
|
|
case 394: return PacketType.RequestTrustedCircuit;
|
|
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 404: return PacketType.SystemMessage;
|
|
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 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;
|
|
}
|
|
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.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.NearestLandingRegionUpdated) return new NearestLandingRegionUpdatedPacket();
|
|
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.KickUserAck) return new KickUserAckPacket();
|
|
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.RequestInventoryAsset) return new RequestInventoryAssetPacket();
|
|
if(type == PacketType.InventoryAssetResponse) return new InventoryAssetResponsePacket();
|
|
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.FormFriendship) return new FormFriendshipPacket();
|
|
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.CreateTrustedCircuit) return new CreateTrustedCircuitPacket();
|
|
if(type == PacketType.DenyTrustedCircuit) return new DenyTrustedCircuitPacket();
|
|
if(type == PacketType.RequestTrustedCircuit) return new RequestTrustedCircuitPacket();
|
|
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.SystemMessage) return new SystemMessagePacket();
|
|
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.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 146: return new NearestLandingRegionUpdatedPacket(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 164: return new KickUserAckPacket(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 282: return new RequestInventoryAssetPacket(header, bytes, ref i);
|
|
case 283: return new InventoryAssetResponsePacket(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 299: return new FormFriendshipPacket(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 392: return new CreateTrustedCircuitPacket(header, bytes, ref i);
|
|
case 393: return new DenyTrustedCircuitPacket(header, bytes, ref i);
|
|
case 394: return new RequestTrustedCircuitPacket(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 404: return new SystemMessagePacket(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 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);
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
throw new MalformedDataException("Unknown packet ID " + header.Frequency + " " + header.ID);
|
|
}
|
|
}
|
|
/// <exclude/>
|
|
public sealed class TestMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class TelehubBlockBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
private byte[] _objectname;
|
|
public byte[] ObjectName
|
|
{
|
|
get { return _objectname; }
|
|
set
|
|
{
|
|
if (value == null) { _objectname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _objectname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _objectname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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;
|
|
while (
|
|
SpawnPointBlockStart < SpawnPointBlock.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
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 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 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 class DataBlock : PacketBlock
|
|
{
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID AvatarID;
|
|
private byte[] _firstname;
|
|
public byte[] FirstName
|
|
{
|
|
get { return _firstname; }
|
|
set
|
|
{
|
|
if (value == null) { _firstname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _firstname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _firstname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _lastname;
|
|
public byte[] LastName
|
|
{
|
|
get { return _lastname; }
|
|
set
|
|
{
|
|
if (value == null) { _lastname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _lastname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _lastname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_firstname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _firstname, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PlacesQueryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 class QueryDataBlock : PacketBlock
|
|
{
|
|
private byte[] _querytext;
|
|
public byte[] QueryText
|
|
{
|
|
get { return _querytext; }
|
|
set
|
|
{
|
|
if (value == null) { _querytext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _querytext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _querytext, 0, value.Length); }
|
|
}
|
|
}
|
|
public uint QueryFlags;
|
|
public sbyte Category;
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 = (ushort)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 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 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 class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID OwnerID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _desc;
|
|
public byte[] Desc
|
|
{
|
|
get { return _desc; }
|
|
set
|
|
{
|
|
if (value == null) { _desc = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _desc = new byte[value.Length]; Buffer.BlockCopy(value, 0, _desc, 0, value.Length); }
|
|
}
|
|
}
|
|
public int ActualArea;
|
|
public int BillableArea;
|
|
public byte Flags;
|
|
public float GlobalX;
|
|
public float GlobalY;
|
|
public float GlobalZ;
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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 = (ushort)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;
|
|
while (
|
|
QueryDataStart < QueryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirFindQueryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
private byte[] _querytext;
|
|
public byte[] QueryText
|
|
{
|
|
get { return _querytext; }
|
|
set
|
|
{
|
|
if (value == null) { _querytext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _querytext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _querytext, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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 class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
private byte[] _querytext;
|
|
public byte[] QueryText
|
|
{
|
|
get { return _querytext; }
|
|
set
|
|
{
|
|
if (value == null) { _querytext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _querytext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _querytext, 0, value.Length); }
|
|
}
|
|
}
|
|
public uint QueryFlags;
|
|
public sbyte Category;
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 = (ushort)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 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 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 class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID ParcelID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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;
|
|
while (
|
|
QueryDataStart < QueryData.Length ||
|
|
QueryRepliesStart < QueryReplies.Length ||
|
|
StatusDataStart < StatusData.Length)
|
|
{
|
|
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) {
|
|
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) {
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirPeopleReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
private byte[] _firstname;
|
|
public byte[] FirstName
|
|
{
|
|
get { return _firstname; }
|
|
set
|
|
{
|
|
if (value == null) { _firstname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _firstname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _firstname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _lastname;
|
|
public byte[] LastName
|
|
{
|
|
get { return _lastname; }
|
|
set
|
|
{
|
|
if (value == null) { _lastname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _lastname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _lastname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _group;
|
|
public byte[] Group
|
|
{
|
|
get { return _group; }
|
|
set
|
|
{
|
|
if (value == null) { _group = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _group = new byte[value.Length]; Buffer.BlockCopy(value, 0, _group, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_firstname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _firstname, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_lastname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _lastname, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
QueryRepliesStart < QueryReplies.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirEventsReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID OwnerID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
public uint EventID;
|
|
private byte[] _date;
|
|
public byte[] Date
|
|
{
|
|
get { return _date; }
|
|
set
|
|
{
|
|
if (value == null) { _date = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _date = new byte[value.Length]; Buffer.BlockCopy(value, 0, _date, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 = (ushort)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 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;
|
|
while (
|
|
QueryRepliesStart < QueryReplies.Length ||
|
|
StatusDataStart < StatusData.Length)
|
|
{
|
|
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) {
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirGroupsReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
private byte[] _groupname;
|
|
public byte[] GroupName
|
|
{
|
|
get { return _groupname; }
|
|
set
|
|
{
|
|
if (value == null) { _groupname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _groupname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _groupname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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;
|
|
while (
|
|
QueryRepliesStart < QueryReplies.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirClassifiedQueryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
private byte[] _querytext;
|
|
public byte[] QueryText
|
|
{
|
|
get { return _querytext; }
|
|
set
|
|
{
|
|
if (value == null) { _querytext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _querytext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _querytext, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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 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 class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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;
|
|
while (
|
|
QueryRepliesStart < QueryReplies.Length ||
|
|
StatusDataStart < StatusData.Length)
|
|
{
|
|
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) {
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarClassifiedReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ClassifiedInfoRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
public UUID CreatorID;
|
|
public uint CreationDate;
|
|
public uint ExpirationDate;
|
|
public uint Category;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _desc;
|
|
public byte[] Desc
|
|
{
|
|
get { return _desc; }
|
|
set
|
|
{
|
|
if (value == null) { _desc = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _desc = new byte[value.Length]; Buffer.BlockCopy(value, 0, _desc, 0, value.Length); }
|
|
}
|
|
}
|
|
public UUID ParcelID;
|
|
public uint ParentEstate;
|
|
public UUID SnapshotID;
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
public Vector3d PosGlobal;
|
|
private byte[] _parcelname;
|
|
public byte[] ParcelName
|
|
{
|
|
get { return _parcelname; }
|
|
set
|
|
{
|
|
if (value == null) { _parcelname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _parcelname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _parcelname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)(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 = (ushort)bytes[i++];
|
|
_simname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _simname, 0, length); i += length;
|
|
PosGlobal.FromBytes(bytes, i); i += 24;
|
|
length = (ushort)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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID ClassifiedID;
|
|
public uint Category;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _desc;
|
|
public byte[] Desc
|
|
{
|
|
get { return _desc; }
|
|
set
|
|
{
|
|
if (value == null) { _desc = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _desc = new byte[value.Length]; Buffer.BlockCopy(value, 0, _desc, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)(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 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 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 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 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 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 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 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 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 class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID ParcelID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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;
|
|
while (
|
|
QueryRepliesStart < QueryReplies.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DirPopularQueryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 class QueryRepliesBlock : PacketBlock
|
|
{
|
|
public UUID ParcelID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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;
|
|
while (
|
|
QueryRepliesStart < QueryReplies.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelInfoRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID ParcelID;
|
|
public UUID OwnerID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _desc;
|
|
public byte[] Desc
|
|
{
|
|
get { return _desc; }
|
|
set
|
|
{
|
|
if (value == null) { _desc = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _desc = new byte[value.Length]; Buffer.BlockCopy(value, 0, _desc, 0, value.Length); }
|
|
}
|
|
}
|
|
public int ActualArea;
|
|
public int BillableArea;
|
|
public byte Flags;
|
|
public float GlobalX;
|
|
public float GlobalY;
|
|
public float GlobalZ;
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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 = (ushort)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 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 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 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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupNoticesListRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID NoticeID;
|
|
public uint Timestamp;
|
|
private byte[] _fromname;
|
|
public byte[] FromName
|
|
{
|
|
get { return _fromname; }
|
|
set
|
|
{
|
|
if (value == null) { _fromname = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _fromname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _fromname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _subject;
|
|
public byte[] Subject
|
|
{
|
|
get { return _subject; }
|
|
set
|
|
{
|
|
if (value == null) { _subject = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _subject = new byte[value.Length]; Buffer.BlockCopy(value, 0, _subject, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
_fromname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _fromname, 0, length); i += length;
|
|
length = (ushort)(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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupNoticeRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 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 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 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 class InfoBlock : PacketBlock
|
|
{
|
|
public uint TeleportFlags;
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 class InfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public uint LocationID;
|
|
public uint SimIP;
|
|
public ushort SimPort;
|
|
public ulong RegionHandle;
|
|
private byte[] _seedcapability;
|
|
public byte[] SeedCapability
|
|
{
|
|
get { return _seedcapability; }
|
|
set
|
|
{
|
|
if (value == null) { _seedcapability = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _seedcapability = new byte[value.Length]; Buffer.BlockCopy(value, 0, _seedcapability, 0, value.Length); }
|
|
}
|
|
}
|
|
public byte SimAccess;
|
|
public uint TeleportFlags;
|
|
|
|
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 = (ushort)(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;
|
|
}
|
|
|
|
}
|
|
|
|
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 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 class InfoBlock : PacketBlock
|
|
{
|
|
public byte LureType;
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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;
|
|
while (
|
|
TargetDataStart < TargetData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TeleportLureRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class InfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
private byte[] _reason;
|
|
public byte[] Reason
|
|
{
|
|
get { return _reason; }
|
|
set
|
|
{
|
|
if (value == null) { _reason = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _reason = new byte[value.Length]; Buffer.BlockCopy(value, 0, _reason, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 class AlertInfoBlock : PacketBlock
|
|
{
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _extraparams;
|
|
public byte[] ExtraParams
|
|
{
|
|
get { return _extraparams; }
|
|
set
|
|
{
|
|
if (value == null) { _extraparams = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _extraparams = new byte[value.Length]; Buffer.BlockCopy(value, 0, _extraparams, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _message, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
AlertInfoStart < AlertInfo.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UndoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RedoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UndoLandPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 class ChatDataBlock : PacketBlock
|
|
{
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)(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 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 class ThrottleBlock : PacketBlock
|
|
{
|
|
public uint GenCounter;
|
|
private byte[] _throttles;
|
|
public byte[] Throttles
|
|
{
|
|
get { return _throttles; }
|
|
set
|
|
{
|
|
if (value == null) { _throttles = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _throttles = new byte[value.Length]; Buffer.BlockCopy(value, 0, _throttles, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 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 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 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 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 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
private byte[] _textureentry;
|
|
public byte[] TextureEntry
|
|
{
|
|
get { return _textureentry; }
|
|
set
|
|
{
|
|
if (value == null) { _textureentry = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _textureentry = new byte[value.Length]; Buffer.BlockCopy(value, 0, _textureentry, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 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 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 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 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 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 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDuplicatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDuplicateOnRayPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectScalePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectRotationPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectFlagUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
|
|
public ObjectFlagUpdatePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ObjectFlagUpdate;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 94;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
AgentData = new AgentDataBlock();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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 ObjectClickActionPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectImagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
private byte[] _mediaurl;
|
|
public byte[] MediaURL
|
|
{
|
|
get { return _mediaurl; }
|
|
set
|
|
{
|
|
if (value == null) { _mediaurl = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _mediaurl = new byte[value.Length]; Buffer.BlockCopy(value, 0, _mediaurl, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _textureentry;
|
|
public byte[] TextureEntry
|
|
{
|
|
get { return _textureentry; }
|
|
set
|
|
{
|
|
if (value == null) { _textureentry = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _textureentry = new byte[value.Length]; Buffer.BlockCopy(value, 0, _textureentry, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_mediaurl = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _mediaurl, 0, length); i += length;
|
|
length = (ushort)(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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectMaterialPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectShapePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectExtraParamsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public ushort ParamType;
|
|
public bool ParamInUse;
|
|
public uint ParamSize;
|
|
private byte[] _paramdata;
|
|
public byte[] ParamData
|
|
{
|
|
get { return _paramdata; }
|
|
set
|
|
{
|
|
if (value == null) { _paramdata = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _paramdata = new byte[value.Length]; Buffer.BlockCopy(value, 0, _paramdata, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectOwnerPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectGroupPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectBuyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class BuyObjectInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectSaleInfoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectNamePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDescriptionPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint LocalID;
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectCategoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectSelectPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDeselectPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectAttachPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDetachPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDropPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectLinkPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDelinkPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectGrabPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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;
|
|
while (
|
|
SurfaceInfoStart < SurfaceInfo.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectGrabUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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;
|
|
while (
|
|
SurfaceInfoStart < SurfaceInfo.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectDeGrabPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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;
|
|
while (
|
|
SurfaceInfoStart < SurfaceInfo.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectSpinStartPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ModifyLandPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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;
|
|
while (
|
|
ParcelDataStart < ParcelData.Length ||
|
|
ModifyBlockExtendedStart < ModifyBlockExtended.Length)
|
|
{
|
|
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) {
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class VelocityInterpolateOnPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class DataBlockBlock : PacketBlock
|
|
{
|
|
private byte[] _filename;
|
|
public byte[] Filename
|
|
{
|
|
get { return _filename; }
|
|
set
|
|
{
|
|
if (value == null) { _filename = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _filename = new byte[value.Length]; Buffer.BlockCopy(value, 0, _filename, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 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 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 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 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 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;
|
|
private byte[] _sysos;
|
|
public byte[] SysOS
|
|
{
|
|
get { return _sysos; }
|
|
set
|
|
{
|
|
if (value == null) { _sysos = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _sysos = new byte[value.Length]; Buffer.BlockCopy(value, 0, _sysos, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _syscpu;
|
|
public byte[] SysCPU
|
|
{
|
|
get { return _syscpu; }
|
|
set
|
|
{
|
|
if (value == null) { _syscpu = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _syscpu = new byte[value.Length]; Buffer.BlockCopy(value, 0, _syscpu, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _sysgpu;
|
|
public byte[] SysGPU
|
|
{
|
|
get { return _sysgpu; }
|
|
set
|
|
{
|
|
if (value == null) { _sysgpu = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _sysgpu = new byte[value.Length]; Buffer.BlockCopy(value, 0, _sysgpu, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_sysos = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _sysos, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_syscpu = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _syscpu, 0, length); i += length;
|
|
length = (ushort)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 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 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 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 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;
|
|
while (
|
|
MiscStatsStart < MiscStats.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptAnswerYesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class ReportDataBlock : PacketBlock
|
|
{
|
|
public byte ReportType;
|
|
public byte Category;
|
|
public Vector3 Position;
|
|
public byte CheckFlags;
|
|
public UUID ScreenshotID;
|
|
public UUID ObjectID;
|
|
public UUID AbuserID;
|
|
private byte[] _abuseregionname;
|
|
public byte[] AbuseRegionName
|
|
{
|
|
get { return _abuseregionname; }
|
|
set
|
|
{
|
|
if (value == null) { _abuseregionname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _abuseregionname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _abuseregionname, 0, value.Length); }
|
|
}
|
|
}
|
|
public UUID AbuseRegionID;
|
|
private byte[] _summary;
|
|
public byte[] Summary
|
|
{
|
|
get { return _summary; }
|
|
set
|
|
{
|
|
if (value == null) { _summary = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _summary = new byte[value.Length]; Buffer.BlockCopy(value, 0, _summary, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _details;
|
|
public byte[] Details
|
|
{
|
|
get { return _details; }
|
|
set
|
|
{
|
|
if (value == null) { _details = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _details = new byte[value.Length]; Buffer.BlockCopy(value, 0, _details, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _versionstring;
|
|
public byte[] VersionString
|
|
{
|
|
get { return _versionstring; }
|
|
set
|
|
{
|
|
if (value == null) { _versionstring = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _versionstring = new byte[value.Length]; Buffer.BlockCopy(value, 0, _versionstring, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_abuseregionname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _abuseregionname, 0, length); i += length;
|
|
AbuseRegionID.FromBytes(bytes, i); i += 16;
|
|
length = (ushort)bytes[i++];
|
|
_summary = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _summary, 0, length); i += length;
|
|
length = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
_details = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _details, 0, length); i += length;
|
|
length = (ushort)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 class AlertDataBlock : PacketBlock
|
|
{
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 class AlertInfoBlock : PacketBlock
|
|
{
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _extraparams;
|
|
public byte[] ExtraParams
|
|
{
|
|
get { return _extraparams; }
|
|
set
|
|
{
|
|
if (value == null) { _extraparams = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _extraparams = new byte[value.Length]; Buffer.BlockCopy(value, 0, _extraparams, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _message, 0, length); i += length;
|
|
length = (ushort)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 += AlertData.Length;
|
|
for (int j = 0; j < AlertInfo.Length; j++)
|
|
length += AlertInfo[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AlertDataBlock AlertData;
|
|
public AlertInfoBlock[] AlertInfo;
|
|
|
|
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;
|
|
}
|
|
|
|
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); }
|
|
}
|
|
|
|
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); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AlertData.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);
|
|
AlertData.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 += AlertData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
AlertData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int AlertInfoStart = 0;
|
|
while (
|
|
AlertInfoStart < AlertInfo.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentAlertMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class AlertDataBlock : PacketBlock
|
|
{
|
|
public bool Modal;
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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;
|
|
while (
|
|
MeanCollisionStart < MeanCollision.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ViewerFrozenMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 class ChatDataBlock : PacketBlock
|
|
{
|
|
private byte[] _fromname;
|
|
public byte[] FromName
|
|
{
|
|
get { return _fromname; }
|
|
set
|
|
{
|
|
if (value == null) { _fromname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _fromname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _fromname, 0, value.Length); }
|
|
}
|
|
}
|
|
public UUID SourceID;
|
|
public UUID OwnerID;
|
|
public byte SourceType;
|
|
public byte ChatType;
|
|
public byte Audible;
|
|
public Vector3 Position;
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 = (ushort)(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 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 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 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;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += Region.Length;
|
|
for (int j = 0; j < Stat.Length; j++)
|
|
length += Stat[j].Length;
|
|
length += PidStat.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RegionBlock Region;
|
|
public StatBlock[] Stat;
|
|
public PidStatBlock PidStat;
|
|
|
|
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();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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; }
|
|
if (Header.AckList != 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);
|
|
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 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 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 class RegionInfoBlock : PacketBlock
|
|
{
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 class RegionInfo2Block : PacketBlock
|
|
{
|
|
private byte[] _productsku;
|
|
public byte[] ProductSKU
|
|
{
|
|
get { return _productsku; }
|
|
set
|
|
{
|
|
if (value == null) { _productsku = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _productsku = new byte[value.Length]; Buffer.BlockCopy(value, 0, _productsku, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _productname;
|
|
public byte[] ProductName
|
|
{
|
|
get { return _productname; }
|
|
set
|
|
{
|
|
if (value == null) { _productname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _productname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _productname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_productsku = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _productsku, 0, length); i += length;
|
|
length = (ushort)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;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RegionInfo.Length;
|
|
length += RegionInfo2.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RegionInfoBlock RegionInfo;
|
|
public RegionInfo2Block RegionInfo2;
|
|
|
|
public RegionInfoPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
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();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RegionInfo.Length;
|
|
length += RegionInfo2.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { 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);
|
|
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 GodUpdateRegionInfoPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class RegionInfoBlock : PacketBlock
|
|
{
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += RegionInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public RegionInfoBlock RegionInfo;
|
|
|
|
public GodUpdateRegionInfoPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
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();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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 NearestLandingRegionUpdatedPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class RegionDataBlock : PacketBlock
|
|
{
|
|
public ulong RegionHandle;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
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));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
Utils.UInt64ToBytes(RegionHandle, bytes, i); i += 8;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += RegionData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RegionDataBlock RegionData;
|
|
|
|
public NearestLandingRegionUpdatedPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.NearestLandingRegionUpdated;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 146;
|
|
Header.Reliable = true;
|
|
RegionData = new RegionDataBlock();
|
|
}
|
|
|
|
public NearestLandingRegionUpdatedPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, 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);
|
|
}
|
|
|
|
public NearestLandingRegionUpdatedPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 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);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += RegionData.Length;
|
|
if (Header.AckList != 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);
|
|
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 RegionHandshakePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class RegionInfoBlock : PacketBlock
|
|
{
|
|
public uint RegionFlags;
|
|
public byte SimAccess;
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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 class RegionInfo3Block : PacketBlock
|
|
{
|
|
public int CPUClassID;
|
|
public int CPURatio;
|
|
private byte[] _coloname;
|
|
public byte[] ColoName
|
|
{
|
|
get { return _coloname; }
|
|
set
|
|
{
|
|
if (value == null) { _coloname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _coloname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _coloname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _productsku;
|
|
public byte[] ProductSKU
|
|
{
|
|
get { return _productsku; }
|
|
set
|
|
{
|
|
if (value == null) { _productsku = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _productsku = new byte[value.Length]; Buffer.BlockCopy(value, 0, _productsku, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _productname;
|
|
public byte[] ProductName
|
|
{
|
|
get { return _productname; }
|
|
set
|
|
{
|
|
if (value == null) { _productname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _productname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _productname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_coloname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _coloname, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_productsku = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _productsku, 0, length); i += length;
|
|
length = (ushort)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;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += RegionInfo.Length;
|
|
length += RegionInfo2.Length;
|
|
length += RegionInfo3.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public RegionInfoBlock RegionInfo;
|
|
public RegionInfo2Block RegionInfo2;
|
|
public RegionInfo3Block RegionInfo3;
|
|
|
|
public RegionHandshakePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
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();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += RegionInfo.Length;
|
|
length += RegionInfo2.Length;
|
|
length += RegionInfo3.Length;
|
|
if (Header.AckList != 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);
|
|
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 RegionHandshakeReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 class TransferInfoBlock : PacketBlock
|
|
{
|
|
public UUID TransferID;
|
|
public int ChannelType;
|
|
public int SourceType;
|
|
public float Priority;
|
|
private byte[] _params;
|
|
public byte[] Params
|
|
{
|
|
get { return _params; }
|
|
set
|
|
{
|
|
if (value == null) { _params = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _params = new byte[value.Length]; Buffer.BlockCopy(value, 0, _params, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 class TransferInfoBlock : PacketBlock
|
|
{
|
|
public UUID TransferID;
|
|
public int ChannelType;
|
|
public int TargetType;
|
|
public int Status;
|
|
public int Size;
|
|
private byte[] _params;
|
|
public byte[] Params
|
|
{
|
|
get { return _params; }
|
|
set
|
|
{
|
|
if (value == null) { _params = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _params = new byte[value.Length]; Buffer.BlockCopy(value, 0, _params, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 class XferIDBlock : PacketBlock
|
|
{
|
|
public ulong ID;
|
|
private byte[] _filename;
|
|
public byte[] Filename
|
|
{
|
|
get { return _filename; }
|
|
set
|
|
{
|
|
if (value == null) { _filename = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _filename = new byte[value.Length]; Buffer.BlockCopy(value, 0, _filename, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
private byte[] _textureentry;
|
|
public byte[] TextureEntry
|
|
{
|
|
get { return _textureentry; }
|
|
set
|
|
{
|
|
if (value == null) { _textureentry = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _textureentry = new byte[value.Length]; Buffer.BlockCopy(value, 0, _textureentry, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 = 11;
|
|
length += Sender.Length;
|
|
length += ObjectData.Length;
|
|
for (int j = 0; j < VisualParam.Length; j++)
|
|
length += VisualParam[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public SenderBlock Sender;
|
|
public ObjectDataBlock ObjectData;
|
|
public VisualParamBlock[] VisualParam;
|
|
|
|
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;
|
|
}
|
|
|
|
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); }
|
|
}
|
|
|
|
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); }
|
|
}
|
|
|
|
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; }
|
|
if (Header.AckList != 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); }
|
|
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 += 1;
|
|
|
|
int VisualParamStart = 0;
|
|
while (
|
|
VisualParamStart < VisualParam.Length)
|
|
{
|
|
int variableLength = 0;
|
|
int VisualParamCount = 0;
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SetFollowCamPropertiesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
CameraPropertyStart < CameraProperty.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ClearFollowCamPropertiesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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;
|
|
while (
|
|
ButtonDataStart < ButtonData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class KickUserPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class UserInfoBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
private byte[] _reason;
|
|
public byte[] Reason
|
|
{
|
|
get { return _reason; }
|
|
set
|
|
{
|
|
if (value == null) { _reason = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _reason = new byte[value.Length]; Buffer.BlockCopy(value, 0, _reason, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 KickUserAckPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class UserInfoBlock : PacketBlock
|
|
{
|
|
public UUID SessionID;
|
|
public uint Flags;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public UserInfoBlock() { }
|
|
public UserInfoBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
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)
|
|
{
|
|
SessionID.ToBytes(bytes, i); i += 16;
|
|
Utils.UIntToBytes(Flags, bytes, i); i += 4;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += UserInfo.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public UserInfoBlock UserInfo;
|
|
|
|
public KickUserAckPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.KickUserAck;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 164;
|
|
Header.Reliable = true;
|
|
UserInfo = new UserInfoBlock();
|
|
}
|
|
|
|
public KickUserAckPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, 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 KickUserAckPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 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 GodKickUserPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class UserInfoBlock : PacketBlock
|
|
{
|
|
public UUID GodID;
|
|
public UUID GodSessionID;
|
|
public UUID AgentID;
|
|
public uint KickFlags;
|
|
private byte[] _reason;
|
|
public byte[] Reason
|
|
{
|
|
get { return _reason; }
|
|
set
|
|
{
|
|
if (value == null) { _reason = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _reason = new byte[value.Length]; Buffer.BlockCopy(value, 0, _reason, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 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 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 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 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 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 class PropertiesDataBlock : PacketBlock
|
|
{
|
|
public UUID ImageID;
|
|
public UUID FLImageID;
|
|
public UUID PartnerID;
|
|
private byte[] _abouttext;
|
|
public byte[] AboutText
|
|
{
|
|
get { return _abouttext; }
|
|
set
|
|
{
|
|
if (value == null) { _abouttext = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _abouttext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _abouttext, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _flabouttext;
|
|
public byte[] FLAboutText
|
|
{
|
|
get { return _flabouttext; }
|
|
set
|
|
{
|
|
if (value == null) { _flabouttext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _flabouttext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _flabouttext, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _bornon;
|
|
public byte[] BornOn
|
|
{
|
|
get { return _bornon; }
|
|
set
|
|
{
|
|
if (value == null) { _bornon = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _bornon = new byte[value.Length]; Buffer.BlockCopy(value, 0, _bornon, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _profileurl;
|
|
public byte[] ProfileURL
|
|
{
|
|
get { return _profileurl; }
|
|
set
|
|
{
|
|
if (value == null) { _profileurl = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _profileurl = new byte[value.Length]; Buffer.BlockCopy(value, 0, _profileurl, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _chartermember;
|
|
public byte[] CharterMember
|
|
{
|
|
get { return _chartermember; }
|
|
set
|
|
{
|
|
if (value == null) { _chartermember = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _chartermember = new byte[value.Length]; Buffer.BlockCopy(value, 0, _chartermember, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
_abouttext = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _abouttext, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_flabouttext = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _flabouttext, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_bornon = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _bornon, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_profileurl = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _profileurl, 0, length); i += length;
|
|
length = (ushort)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 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 class PropertiesDataBlock : PacketBlock
|
|
{
|
|
public uint WantToMask;
|
|
private byte[] _wanttotext;
|
|
public byte[] WantToText
|
|
{
|
|
get { return _wanttotext; }
|
|
set
|
|
{
|
|
if (value == null) { _wanttotext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _wanttotext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _wanttotext, 0, value.Length); }
|
|
}
|
|
}
|
|
public uint SkillsMask;
|
|
private byte[] _skillstext;
|
|
public byte[] SkillsText
|
|
{
|
|
get { return _skillstext; }
|
|
set
|
|
{
|
|
if (value == null) { _skillstext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _skillstext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _skillstext, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _languagestext;
|
|
public byte[] LanguagesText
|
|
{
|
|
get { return _languagestext; }
|
|
set
|
|
{
|
|
if (value == null) { _languagestext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _languagestext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _languagestext, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 = (ushort)bytes[i++];
|
|
_skillstext = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _skillstext, 0, length); i += length;
|
|
length = (ushort)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 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 class GroupDataBlock : PacketBlock
|
|
{
|
|
public ulong GroupPowers;
|
|
public bool AcceptNotices;
|
|
private byte[] _grouptitle;
|
|
public byte[] GroupTitle
|
|
{
|
|
get { return _grouptitle; }
|
|
set
|
|
{
|
|
if (value == null) { _grouptitle = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _grouptitle = new byte[value.Length]; Buffer.BlockCopy(value, 0, _grouptitle, 0, value.Length); }
|
|
}
|
|
}
|
|
public UUID GroupID;
|
|
private byte[] _groupname;
|
|
public byte[] GroupName
|
|
{
|
|
get { return _groupname; }
|
|
set
|
|
{
|
|
if (value == null) { _groupname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _groupname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _groupname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_grouptitle = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _grouptitle, 0, length); i += length;
|
|
GroupID.FromBytes(bytes, i); i += 16;
|
|
length = (ushort)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 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 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 class PropertiesDataBlock : PacketBlock
|
|
{
|
|
public UUID ImageID;
|
|
public UUID FLImageID;
|
|
private byte[] _abouttext;
|
|
public byte[] AboutText
|
|
{
|
|
get { return _abouttext; }
|
|
set
|
|
{
|
|
if (value == null) { _abouttext = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _abouttext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _abouttext, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _flabouttext;
|
|
public byte[] FLAboutText
|
|
{
|
|
get { return _flabouttext; }
|
|
set
|
|
{
|
|
if (value == null) { _flabouttext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _flabouttext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _flabouttext, 0, value.Length); }
|
|
}
|
|
}
|
|
public bool AllowPublish;
|
|
public bool MaturePublish;
|
|
private byte[] _profileurl;
|
|
public byte[] ProfileURL
|
|
{
|
|
get { return _profileurl; }
|
|
set
|
|
{
|
|
if (value == null) { _profileurl = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _profileurl = new byte[value.Length]; Buffer.BlockCopy(value, 0, _profileurl, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
_abouttext = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _abouttext, 0, length); i += length;
|
|
length = (ushort)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 = (ushort)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 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 class PropertiesDataBlock : PacketBlock
|
|
{
|
|
public uint WantToMask;
|
|
private byte[] _wanttotext;
|
|
public byte[] WantToText
|
|
{
|
|
get { return _wanttotext; }
|
|
set
|
|
{
|
|
if (value == null) { _wanttotext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _wanttotext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _wanttotext, 0, value.Length); }
|
|
}
|
|
}
|
|
public uint SkillsMask;
|
|
private byte[] _skillstext;
|
|
public byte[] SkillsText
|
|
{
|
|
get { return _skillstext; }
|
|
set
|
|
{
|
|
if (value == null) { _skillstext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _skillstext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _skillstext, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _languagestext;
|
|
public byte[] LanguagesText
|
|
{
|
|
get { return _languagestext; }
|
|
set
|
|
{
|
|
if (value == null) { _languagestext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _languagestext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _languagestext, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 = (ushort)bytes[i++];
|
|
_skillstext = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _skillstext, 0, length); i += length;
|
|
length = (ushort)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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID TargetID;
|
|
private byte[] _notes;
|
|
public byte[] Notes
|
|
{
|
|
get { return _notes; }
|
|
set
|
|
{
|
|
if (value == null) { _notes = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _notes = new byte[value.Length]; Buffer.BlockCopy(value, 0, _notes, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID TargetID;
|
|
private byte[] _notes;
|
|
public byte[] Notes
|
|
{
|
|
get { return _notes; }
|
|
set
|
|
{
|
|
if (value == null) { _notes = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _notes = new byte[value.Length]; Buffer.BlockCopy(value, 0, _notes, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID PickID;
|
|
private byte[] _pickname;
|
|
public byte[] PickName
|
|
{
|
|
get { return _pickname; }
|
|
set
|
|
{
|
|
if (value == null) { _pickname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _pickname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _pickname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EventInfoRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class EventDataBlock : PacketBlock
|
|
{
|
|
public uint EventID;
|
|
private byte[] _creator;
|
|
public byte[] Creator
|
|
{
|
|
get { return _creator; }
|
|
set
|
|
{
|
|
if (value == null) { _creator = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _creator = new byte[value.Length]; Buffer.BlockCopy(value, 0, _creator, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _category;
|
|
public byte[] Category
|
|
{
|
|
get { return _category; }
|
|
set
|
|
{
|
|
if (value == null) { _category = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _category = new byte[value.Length]; Buffer.BlockCopy(value, 0, _category, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _desc;
|
|
public byte[] Desc
|
|
{
|
|
get { return _desc; }
|
|
set
|
|
{
|
|
if (value == null) { _desc = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _desc = new byte[value.Length]; Buffer.BlockCopy(value, 0, _desc, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _date;
|
|
public byte[] Date
|
|
{
|
|
get { return _date; }
|
|
set
|
|
{
|
|
if (value == null) { _date = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _date = new byte[value.Length]; Buffer.BlockCopy(value, 0, _date, 0, value.Length); }
|
|
}
|
|
}
|
|
public uint DateUTC;
|
|
public uint Duration;
|
|
public uint Cover;
|
|
public uint Amount;
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_creator = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _creator, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_category = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _category, 0, length); i += length;
|
|
length = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
_desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _desc, 0, length); i += length;
|
|
length = (ushort)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 = (ushort)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 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 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 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 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 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 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 class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
private byte[] _querytext;
|
|
public byte[] QueryText
|
|
{
|
|
get { return _querytext; }
|
|
set
|
|
{
|
|
if (value == null) { _querytext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _querytext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _querytext, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID PickID;
|
|
public UUID CreatorID;
|
|
public bool TopPick;
|
|
public UUID ParcelID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _desc;
|
|
public byte[] Desc
|
|
{
|
|
get { return _desc; }
|
|
set
|
|
{
|
|
if (value == null) { _desc = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _desc = new byte[value.Length]; Buffer.BlockCopy(value, 0, _desc, 0, value.Length); }
|
|
}
|
|
}
|
|
public UUID SnapshotID;
|
|
private byte[] _user;
|
|
public byte[] User
|
|
{
|
|
get { return _user; }
|
|
set
|
|
{
|
|
if (value == null) { _user = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _user = new byte[value.Length]; Buffer.BlockCopy(value, 0, _user, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _originalname;
|
|
public byte[] OriginalName
|
|
{
|
|
get { return _originalname; }
|
|
set
|
|
{
|
|
if (value == null) { _originalname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _originalname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _originalname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)(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 = (ushort)bytes[i++];
|
|
_user = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _user, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_originalname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _originalname, 0, length); i += length;
|
|
length = (ushort)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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID PickID;
|
|
public UUID CreatorID;
|
|
public bool TopPick;
|
|
public UUID ParcelID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _desc;
|
|
public byte[] Desc
|
|
{
|
|
get { return _desc; }
|
|
set
|
|
{
|
|
if (value == null) { _desc = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _desc = new byte[value.Length]; Buffer.BlockCopy(value, 0, _desc, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)(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 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 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 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 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID TaskID;
|
|
public UUID ItemID;
|
|
private byte[] _objectname;
|
|
public byte[] ObjectName
|
|
{
|
|
get { return _objectname; }
|
|
set
|
|
{
|
|
if (value == null) { _objectname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _objectname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _objectname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _objectowner;
|
|
public byte[] ObjectOwner
|
|
{
|
|
get { return _objectowner; }
|
|
set
|
|
{
|
|
if (value == null) { _objectowner = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _objectowner = new byte[value.Length]; Buffer.BlockCopy(value, 0, _objectowner, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_objectname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _objectname, 0, length); i += length;
|
|
length = (ushort)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;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock Data;
|
|
|
|
public ScriptQuestionPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.ScriptQuestion;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 188;
|
|
Header.Reliable = true;
|
|
Data = new DataBlock();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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 ScriptControlChangePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptDialogPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class DataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
private byte[] _firstname;
|
|
public byte[] FirstName
|
|
{
|
|
get { return _firstname; }
|
|
set
|
|
{
|
|
if (value == null) { _firstname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _firstname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _firstname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _lastname;
|
|
public byte[] LastName
|
|
{
|
|
get { return _lastname; }
|
|
set
|
|
{
|
|
if (value == null) { _lastname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _lastname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _lastname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _objectname;
|
|
public byte[] ObjectName
|
|
{
|
|
get { return _objectname; }
|
|
set
|
|
{
|
|
if (value == null) { _objectname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _objectname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _objectname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_firstname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _firstname, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_lastname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _lastname, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_objectname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _objectname, 0, length); i += length;
|
|
length = (ushort)(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 class ButtonsBlock : PacketBlock
|
|
{
|
|
private byte[] _buttonlabel;
|
|
public byte[] ButtonLabel
|
|
{
|
|
get { return _buttonlabel; }
|
|
set
|
|
{
|
|
if (value == null) { _buttonlabel = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _buttonlabel = new byte[value.Length]; Buffer.BlockCopy(value, 0, _buttonlabel, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 11;
|
|
length += Data.Length;
|
|
for (int j = 0; j < Buttons.Length; j++)
|
|
length += Buttons[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlock Data;
|
|
public ButtonsBlock[] Buttons;
|
|
|
|
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;
|
|
}
|
|
|
|
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); }
|
|
}
|
|
|
|
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); }
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += Data.Length;
|
|
length++;
|
|
for (int j = 0; j < Buttons.Length; j++) { length += Buttons[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); }
|
|
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 ButtonsStart = 0;
|
|
while (
|
|
ButtonsStart < Buttons.Length)
|
|
{
|
|
int variableLength = 0;
|
|
int ButtonsCount = 0;
|
|
|
|
i = ButtonsStart;
|
|
while (fixedLength + variableLength + acksLength < Packet.MTU && i < Buttons.Length) {
|
|
int blockLength = Buttons[i].Length;
|
|
if (fixedLength + variableLength + blockLength + acksLength <= MTU) {
|
|
variableLength += blockLength;
|
|
++ButtonsCount;
|
|
}
|
|
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;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ScriptDialogReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public int ChatChannel;
|
|
public int ButtonIndex;
|
|
private byte[] _buttonlabel;
|
|
public byte[] ButtonLabel
|
|
{
|
|
get { return _buttonlabel; }
|
|
set
|
|
{
|
|
if (value == null) { _buttonlabel = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _buttonlabel = new byte[value.Length]; Buffer.BlockCopy(value, 0, _buttonlabel, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 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 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 class DataBlock : PacketBlock
|
|
{
|
|
private byte[] _objectname;
|
|
public byte[] ObjectName
|
|
{
|
|
get { return _objectname; }
|
|
set
|
|
{
|
|
if (value == null) { _objectname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _objectname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _objectname, 0, value.Length); }
|
|
}
|
|
}
|
|
public UUID ObjectID;
|
|
public UUID OwnerID;
|
|
public bool OwnerIsGroup;
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _url;
|
|
public byte[] URL
|
|
{
|
|
get { return _url; }
|
|
set
|
|
{
|
|
if (value == null) { _url = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _url = new byte[value.Length]; Buffer.BlockCopy(value, 0, _url, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 = (ushort)bytes[i++];
|
|
_message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _message, 0, length); i += length;
|
|
length = (ushort)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 class DataBlock : PacketBlock
|
|
{
|
|
private byte[] _objectname;
|
|
public byte[] ObjectName
|
|
{
|
|
get { return _objectname; }
|
|
set
|
|
{
|
|
if (value == null) { _objectname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _objectname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _objectname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_objectname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _objectname, 0, length); i += length;
|
|
length = (ushort)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 class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int SequenceID;
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 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 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 class ParcelDataBlock : PacketBlock
|
|
{
|
|
public int LocalID;
|
|
public uint Flags;
|
|
public uint ParcelFlags;
|
|
public int SalePrice;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _desc;
|
|
public byte[] Desc
|
|
{
|
|
get { return _desc; }
|
|
set
|
|
{
|
|
if (value == null) { _desc = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _desc = new byte[value.Length]; Buffer.BlockCopy(value, 0, _desc, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _musicurl;
|
|
public byte[] MusicURL
|
|
{
|
|
get { return _musicurl; }
|
|
set
|
|
{
|
|
if (value == null) { _musicurl = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _musicurl = new byte[value.Length]; Buffer.BlockCopy(value, 0, _musicurl, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _mediaurl;
|
|
public byte[] MediaURL
|
|
{
|
|
get { return _mediaurl; }
|
|
set
|
|
{
|
|
if (value == null) { _mediaurl = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _mediaurl = new byte[value.Length]; Buffer.BlockCopy(value, 0, _mediaurl, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _desc, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_musicurl = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _musicurl, 0, length); i += length;
|
|
length = (ushort)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 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 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 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 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;
|
|
while (
|
|
TaskIDsStart < TaskIDs.Length ||
|
|
OwnerIDsStart < OwnerIDs.Length)
|
|
{
|
|
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) {
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelSetOtherCleanTimePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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;
|
|
while (
|
|
TaskIDsStart < TaskIDs.Length ||
|
|
OwnerIDsStart < OwnerIDs.Length)
|
|
{
|
|
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) {
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelSelectObjectsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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;
|
|
while (
|
|
ReturnIDsStart < ReturnIDs.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EstateCovenantRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class DataBlock : PacketBlock
|
|
{
|
|
public UUID CovenantID;
|
|
public uint CovenantTimestamp;
|
|
private byte[] _estatename;
|
|
public byte[] EstateName
|
|
{
|
|
get { return _estatename; }
|
|
set
|
|
{
|
|
if (value == null) { _estatename = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _estatename = new byte[value.Length]; Buffer.BlockCopy(value, 0, _estatename, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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 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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelBuyPassPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 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 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 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;
|
|
while (
|
|
ParcelDataStart < ParcelData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelJoinPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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;
|
|
while (
|
|
ListStart < List.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelAccessListUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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;
|
|
while (
|
|
ListStart < List.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelDwellRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 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 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 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;
|
|
while (
|
|
UUIDNameBlockStart < UUIDNameBlock.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UUIDNameReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class UUIDNameBlockBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
private byte[] _firstname;
|
|
public byte[] FirstName
|
|
{
|
|
get { return _firstname; }
|
|
set
|
|
{
|
|
if (value == null) { _firstname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _firstname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _firstname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _lastname;
|
|
public byte[] LastName
|
|
{
|
|
get { return _lastname; }
|
|
set
|
|
{
|
|
if (value == null) { _lastname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _lastname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _lastname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_firstname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _firstname, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
UUIDNameBlockStart < UUIDNameBlock.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UUIDGroupNameRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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;
|
|
while (
|
|
UUIDNameBlockStart < UUIDNameBlock.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UUIDGroupNameReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class UUIDNameBlockBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
private byte[] _groupname;
|
|
public byte[] GroupName
|
|
{
|
|
get { return _groupname; }
|
|
set
|
|
{
|
|
if (value == null) { _groupname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _groupname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _groupname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
UUIDNameBlockStart < UUIDNameBlock.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChildAgentDyingPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 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 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 class RequesterBlock : PacketBlock
|
|
{
|
|
public UUID SourceID;
|
|
public UUID RequestID;
|
|
public UUID SearchID;
|
|
public Vector3 SearchPos;
|
|
public Quaternion SearchDir;
|
|
private byte[] _searchname;
|
|
public byte[] SearchName
|
|
{
|
|
get { return _searchname; }
|
|
set
|
|
{
|
|
if (value == null) { _searchname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _searchname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _searchname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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 class SensedDataBlock : PacketBlock
|
|
{
|
|
public UUID ObjectID;
|
|
public UUID OwnerID;
|
|
public UUID GroupID;
|
|
public Vector3 Position;
|
|
public Vector3 Velocity;
|
|
public Quaternion Rotation;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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;
|
|
while (
|
|
SensedDataStart < SensedData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CompleteAgentMovementPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class SimDataBlock : PacketBlock
|
|
{
|
|
private byte[] _channelversion;
|
|
public byte[] ChannelVersion
|
|
{
|
|
get { return _channelversion; }
|
|
set
|
|
{
|
|
if (value == null) { _channelversion = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _channelversion = new byte[value.Length]; Buffer.BlockCopy(value, 0, _channelversion, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 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 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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImprovedInstantMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
private byte[] _fromagentname;
|
|
public byte[] FromAgentName
|
|
{
|
|
get { return _fromagentname; }
|
|
set
|
|
{
|
|
if (value == null) { _fromagentname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _fromagentname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _fromagentname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _binarybucket;
|
|
public byte[] BinaryBucket
|
|
{
|
|
get { return _binarybucket; }
|
|
set
|
|
{
|
|
if (value == null) { _binarybucket = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _binarybucket = new byte[value.Length]; Buffer.BlockCopy(value, 0, _binarybucket, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_fromagentname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _fromagentname, 0, length); i += length;
|
|
length = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
_message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _message, 0, length); i += length;
|
|
length = (ushort)(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;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MessageBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public MessageBlockBlock MessageBlock;
|
|
|
|
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();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += AgentData.Length;
|
|
length += MessageBlock.Length;
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { 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);
|
|
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 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 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 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;
|
|
while (
|
|
LocationBlockStart < LocationBlock.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestGodlikePowersPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 class MethodDataBlock : PacketBlock
|
|
{
|
|
private byte[] _method;
|
|
public byte[] Method
|
|
{
|
|
get { return _method; }
|
|
set
|
|
{
|
|
if (value == null) { _method = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _method = new byte[value.Length]; Buffer.BlockCopy(value, 0, _method, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 class ParamListBlock : PacketBlock
|
|
{
|
|
private byte[] _parameter;
|
|
public byte[] Parameter
|
|
{
|
|
get { return _parameter; }
|
|
set
|
|
{
|
|
if (value == null) { _parameter = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _parameter = new byte[value.Length]; Buffer.BlockCopy(value, 0, _parameter, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
ParamListStart < ParamList.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EstateOwnerMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class MethodDataBlock : PacketBlock
|
|
{
|
|
private byte[] _method;
|
|
public byte[] Method
|
|
{
|
|
get { return _method; }
|
|
set
|
|
{
|
|
if (value == null) { _method = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _method = new byte[value.Length]; Buffer.BlockCopy(value, 0, _method, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 class ParamListBlock : PacketBlock
|
|
{
|
|
private byte[] _parameter;
|
|
public byte[] Parameter
|
|
{
|
|
get { return _parameter; }
|
|
set
|
|
{
|
|
if (value == null) { _parameter = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _parameter = new byte[value.Length]; Buffer.BlockCopy(value, 0, _parameter, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
ParamListStart < ParamList.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GenericMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class MethodDataBlock : PacketBlock
|
|
{
|
|
private byte[] _method;
|
|
public byte[] Method
|
|
{
|
|
get { return _method; }
|
|
set
|
|
{
|
|
if (value == null) { _method = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _method = new byte[value.Length]; Buffer.BlockCopy(value, 0, _method, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 class ParamListBlock : PacketBlock
|
|
{
|
|
private byte[] _parameter;
|
|
public byte[] Parameter
|
|
{
|
|
get { return _parameter; }
|
|
set
|
|
{
|
|
if (value == null) { _parameter = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _parameter = new byte[value.Length]; Buffer.BlockCopy(value, 0, _parameter, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
ParamListStart < ParamList.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MuteListRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class MuteDataBlock : PacketBlock
|
|
{
|
|
public UUID MuteID;
|
|
private byte[] _mutename;
|
|
public byte[] MuteName
|
|
{
|
|
get { return _mutename; }
|
|
set
|
|
{
|
|
if (value == null) { _mutename = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _mutename = new byte[value.Length]; Buffer.BlockCopy(value, 0, _mutename, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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 class MuteDataBlock : PacketBlock
|
|
{
|
|
public UUID MuteID;
|
|
private byte[] _mutename;
|
|
public byte[] MuteName
|
|
{
|
|
get { return _mutename; }
|
|
set
|
|
{
|
|
if (value == null) { _mutename = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _mutename = new byte[value.Length]; Buffer.BlockCopy(value, 0, _mutename, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 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 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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UpdateCreateInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoveInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID FolderID;
|
|
private byte[] _newname;
|
|
public byte[] NewName
|
|
{
|
|
get { return _newname; }
|
|
set
|
|
{
|
|
if (value == null) { _newname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _newname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _newname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CopyInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class InventoryDataBlock : PacketBlock
|
|
{
|
|
public uint CallbackID;
|
|
public UUID OldAgentID;
|
|
public UUID OldItemID;
|
|
public UUID NewFolderID;
|
|
private byte[] _newname;
|
|
public byte[] NewName
|
|
{
|
|
get { return _newname; }
|
|
set
|
|
{
|
|
if (value == null) { _newname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _newname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _newname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RemoveInventoryItemPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChangeInventoryItemFlagsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SaveAssetIntoInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public UUID ParentID;
|
|
public sbyte Type;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public UUID ParentID;
|
|
public sbyte Type;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
FolderDataStart < FolderData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MoveInventoryFolderPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RemoveInventoryFolderPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
FolderDataStart < FolderData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FetchInventoryDescendentsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public UUID ParentID;
|
|
public sbyte Type;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
FolderDataStart < FolderData.Length ||
|
|
ItemDataStart < ItemData.Length)
|
|
{
|
|
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) {
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FetchInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class FetchInventoryReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class BulkUpdateInventoryPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class FolderDataBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
public UUID ParentID;
|
|
public sbyte Type;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
FolderDataStart < FolderData.Length ||
|
|
ItemDataStart < ItemData.Length)
|
|
{
|
|
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) {
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestInventoryAssetPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
public UUID AgentID;
|
|
public UUID OwnerID;
|
|
public UUID ItemID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 64;
|
|
}
|
|
}
|
|
|
|
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;
|
|
AgentID.FromBytes(bytes, i); i += 16;
|
|
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)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
AgentID.ToBytes(bytes, i); i += 16;
|
|
OwnerID.ToBytes(bytes, i); i += 16;
|
|
ItemID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += QueryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public QueryDataBlock QueryData;
|
|
|
|
public RequestInventoryAssetPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RequestInventoryAsset;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 282;
|
|
Header.Reliable = true;
|
|
QueryData = new QueryDataBlock();
|
|
}
|
|
|
|
public RequestInventoryAssetPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public RequestInventoryAssetPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
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);
|
|
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 InventoryAssetResponsePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class QueryDataBlock : PacketBlock
|
|
{
|
|
public UUID QueryID;
|
|
public UUID AssetID;
|
|
public bool IsReadable;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 33;
|
|
}
|
|
}
|
|
|
|
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;
|
|
AssetID.FromBytes(bytes, i); i += 16;
|
|
IsReadable = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
QueryID.ToBytes(bytes, i); i += 16;
|
|
AssetID.ToBytes(bytes, i); i += 16;
|
|
bytes[i++] = (byte)((IsReadable) ? 1 : 0);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += QueryData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public QueryDataBlock QueryData;
|
|
|
|
public InventoryAssetResponsePacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.InventoryAssetResponse;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 283;
|
|
Header.Reliable = true;
|
|
QueryData = new QueryDataBlock();
|
|
}
|
|
|
|
public InventoryAssetResponsePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)
|
|
{
|
|
Header.FromBytes(bytes, ref i, ref packetEnd);
|
|
if (Header.Zerocoded && zeroBuffer != null)
|
|
{
|
|
packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;
|
|
bytes = zeroBuffer;
|
|
}
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public InventoryAssetResponsePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(head, bytes, ref i, ref packetEnd);
|
|
}
|
|
|
|
override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)
|
|
{
|
|
Header = header;
|
|
QueryData.FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
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);
|
|
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 RemoveInventoryObjectsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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;
|
|
while (
|
|
FolderDataStart < FolderData.Length ||
|
|
ItemDataStart < ItemData.Length)
|
|
{
|
|
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) {
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class PurgeInventoryDescendentsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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 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 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 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 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 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 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 class InventoryDataBlock : PacketBlock
|
|
{
|
|
public UUID TaskID;
|
|
public short Serial;
|
|
private byte[] _filename;
|
|
public byte[] Filename
|
|
{
|
|
get { return _filename; }
|
|
set
|
|
{
|
|
if (value == null) { _filename = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _filename = new byte[value.Length]; Buffer.BlockCopy(value, 0, _filename, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DeRezAckPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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 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 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 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 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;
|
|
while (
|
|
InventoryDataStart < InventoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AcceptFriendshipPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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;
|
|
while (
|
|
FolderDataStart < FolderData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DeclineFriendshipPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 FormFriendshipPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class AgentBlockBlock : PacketBlock
|
|
{
|
|
public UUID SourceID;
|
|
public UUID DestID;
|
|
|
|
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
|
|
{
|
|
SourceID.FromBytes(bytes, i); i += 16;
|
|
DestID.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;
|
|
DestID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += AgentBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentBlockBlock AgentBlock;
|
|
|
|
public FormFriendshipPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.FormFriendship;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 299;
|
|
Header.Reliable = true;
|
|
AgentBlock = new AgentBlockBlock();
|
|
}
|
|
|
|
public FormFriendshipPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, 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);
|
|
}
|
|
|
|
public FormFriendshipPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 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);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
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);
|
|
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 TerminateFriendshipPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 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;
|
|
while (
|
|
FolderDataStart < FolderData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DeclineCallingCardPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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 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 class InventoryBlockBlock : PacketBlock
|
|
{
|
|
public uint CallbackID;
|
|
public UUID FolderID;
|
|
public UUID TransactionID;
|
|
public uint NextOwnerMask;
|
|
public sbyte Type;
|
|
public sbyte InvType;
|
|
public byte WearableType;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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 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 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 class InventoryBlockBlock : PacketBlock
|
|
{
|
|
public UUID FolderID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 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 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 class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID SourceID;
|
|
public UUID DestID;
|
|
public byte Flags;
|
|
public int Amount;
|
|
public byte AggregatePermNextOwner;
|
|
public byte AggregatePermInventory;
|
|
public int TransactionType;
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 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 class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID TransactionID;
|
|
public bool TransactionSuccess;
|
|
public int MoneyBalance;
|
|
public int SquareMetersCredit;
|
|
public int SquareMetersCommitted;
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += MoneyData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public MoneyDataBlock MoneyData;
|
|
|
|
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();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
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);
|
|
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 RoutedMoneyBalanceReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID TransactionID;
|
|
public bool TransactionSuccess;
|
|
public int MoneyBalance;
|
|
public int SquareMetersCredit;
|
|
public int SquareMetersCommitted;
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += TargetBlock.Length;
|
|
length += MoneyData.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public TargetBlockBlock TargetBlock;
|
|
public MoneyDataBlock MoneyData;
|
|
|
|
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();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
int length = 10;
|
|
length += TargetBlock.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);
|
|
TargetBlock.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 ActivateGesturesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DeactivateGesturesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MuteListUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class MuteDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
private byte[] _filename;
|
|
public byte[] Filename
|
|
{
|
|
get { return _filename; }
|
|
set
|
|
{
|
|
if (value == null) { _filename = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _filename = new byte[value.Length]; Buffer.BlockCopy(value, 0, _filename, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 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 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;
|
|
while (
|
|
RightsStart < Rights.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChangeUserRightsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
RightsStart < Rights.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class OnlineNotificationPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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;
|
|
while (
|
|
AgentBlockStart < AgentBlock.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class OfflineNotificationPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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;
|
|
while (
|
|
AgentBlockStart < AgentBlock.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SetStartLocationRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class StartLocationDataBlock : PacketBlock
|
|
{
|
|
private byte[] _simname;
|
|
public byte[] SimName
|
|
{
|
|
get { return _simname; }
|
|
set
|
|
{
|
|
if (value == null) { _simname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simname, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 class AssetBlockBlock : PacketBlock
|
|
{
|
|
public UUID TransactionID;
|
|
public sbyte Type;
|
|
public bool Tempfile;
|
|
public bool StoreLocal;
|
|
private byte[] _assetdata;
|
|
public byte[] AssetData
|
|
{
|
|
get { return _assetdata; }
|
|
set
|
|
{
|
|
if (value == null) { _assetdata = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _assetdata = new byte[value.Length]; Buffer.BlockCopy(value, 0, _assetdata, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 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 class GroupDataBlock : PacketBlock
|
|
{
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _charter;
|
|
public byte[] Charter
|
|
{
|
|
get { return _charter; }
|
|
set
|
|
{
|
|
if (value == null) { _charter = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _charter = new byte[value.Length]; Buffer.BlockCopy(value, 0, _charter, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)(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 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 class ReplyDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public bool Success;
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
private byte[] _charter;
|
|
public byte[] Charter
|
|
{
|
|
get { return _charter; }
|
|
set
|
|
{
|
|
if (value == null) { _charter = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _charter = new byte[value.Length]; Buffer.BlockCopy(value, 0, _charter, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)(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 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 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;
|
|
while (
|
|
RoleChangeStart < RoleChange.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class JoinGroupRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 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;
|
|
while (
|
|
EjectDataStart < EjectData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class EjectGroupMemberReplyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 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 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 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 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;
|
|
while (
|
|
InviteDataStart < InviteData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupProfileRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _charter;
|
|
public byte[] Charter
|
|
{
|
|
get { return _charter; }
|
|
set
|
|
{
|
|
if (value == null) { _charter = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _charter = new byte[value.Length]; Buffer.BlockCopy(value, 0, _charter, 0, value.Length); }
|
|
}
|
|
}
|
|
public bool ShowInList;
|
|
private byte[] _membertitle;
|
|
public byte[] MemberTitle
|
|
{
|
|
get { return _membertitle; }
|
|
set
|
|
{
|
|
if (value == null) { _membertitle = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _membertitle = new byte[value.Length]; Buffer.BlockCopy(value, 0, _membertitle, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)(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 = (ushort)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 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 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 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 class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public int IntervalDays;
|
|
public int CurrentInterval;
|
|
private byte[] _startdate;
|
|
public byte[] StartDate
|
|
{
|
|
get { return _startdate; }
|
|
set
|
|
{
|
|
if (value == null) { _startdate = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _startdate = new byte[value.Length]; Buffer.BlockCopy(value, 0, _startdate, 0, value.Length); }
|
|
}
|
|
}
|
|
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;
|
|
private byte[] _lasttaxdate;
|
|
public byte[] LastTaxDate
|
|
{
|
|
get { return _lasttaxdate; }
|
|
set
|
|
{
|
|
if (value == null) { _lasttaxdate = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _lasttaxdate = new byte[value.Length]; Buffer.BlockCopy(value, 0, _lasttaxdate, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _taxdate;
|
|
public byte[] TaxDate
|
|
{
|
|
get { return _taxdate; }
|
|
set
|
|
{
|
|
if (value == null) { _taxdate = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _taxdate = new byte[value.Length]; Buffer.BlockCopy(value, 0, _taxdate, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 = (ushort)bytes[i++];
|
|
_lasttaxdate = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _lasttaxdate, 0, length); i += length;
|
|
length = (ushort)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 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 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 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 class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public int IntervalDays;
|
|
public int CurrentInterval;
|
|
private byte[] _startdate;
|
|
public byte[] StartDate
|
|
{
|
|
get { return _startdate; }
|
|
set
|
|
{
|
|
if (value == null) { _startdate = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _startdate = new byte[value.Length]; Buffer.BlockCopy(value, 0, _startdate, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 class HistoryDataBlock : PacketBlock
|
|
{
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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;
|
|
while (
|
|
HistoryDataStart < HistoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupAccountTransactionsRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class MoneyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public int IntervalDays;
|
|
public int CurrentInterval;
|
|
private byte[] _startdate;
|
|
public byte[] StartDate
|
|
{
|
|
get { return _startdate; }
|
|
set
|
|
{
|
|
if (value == null) { _startdate = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _startdate = new byte[value.Length]; Buffer.BlockCopy(value, 0, _startdate, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 class HistoryDataBlock : PacketBlock
|
|
{
|
|
private byte[] _time;
|
|
public byte[] Time
|
|
{
|
|
get { return _time; }
|
|
set
|
|
{
|
|
if (value == null) { _time = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _time = new byte[value.Length]; Buffer.BlockCopy(value, 0, _time, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _user;
|
|
public byte[] User
|
|
{
|
|
get { return _user; }
|
|
set
|
|
{
|
|
if (value == null) { _user = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _user = new byte[value.Length]; Buffer.BlockCopy(value, 0, _user, 0, value.Length); }
|
|
}
|
|
}
|
|
public int Type;
|
|
private byte[] _item;
|
|
public byte[] Item
|
|
{
|
|
get { return _item; }
|
|
set
|
|
{
|
|
if (value == null) { _item = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _item = new byte[value.Length]; Buffer.BlockCopy(value, 0, _item, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_time = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _time, 0, length); i += length;
|
|
length = (ushort)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 = (ushort)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;
|
|
while (
|
|
HistoryDataStart < HistoryData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupActiveProposalsRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 class ProposalDataBlock : PacketBlock
|
|
{
|
|
public UUID VoteID;
|
|
public UUID VoteInitiator;
|
|
private byte[] _tersedateid;
|
|
public byte[] TerseDateID
|
|
{
|
|
get { return _tersedateid; }
|
|
set
|
|
{
|
|
if (value == null) { _tersedateid = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _tersedateid = new byte[value.Length]; Buffer.BlockCopy(value, 0, _tersedateid, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _startdatetime;
|
|
public byte[] StartDateTime
|
|
{
|
|
get { return _startdatetime; }
|
|
set
|
|
{
|
|
if (value == null) { _startdatetime = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _startdatetime = new byte[value.Length]; Buffer.BlockCopy(value, 0, _startdatetime, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _enddatetime;
|
|
public byte[] EndDateTime
|
|
{
|
|
get { return _enddatetime; }
|
|
set
|
|
{
|
|
if (value == null) { _enddatetime = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _enddatetime = new byte[value.Length]; Buffer.BlockCopy(value, 0, _enddatetime, 0, value.Length); }
|
|
}
|
|
}
|
|
public bool AlreadyVoted;
|
|
private byte[] _votecast;
|
|
public byte[] VoteCast
|
|
{
|
|
get { return _votecast; }
|
|
set
|
|
{
|
|
if (value == null) { _votecast = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _votecast = new byte[value.Length]; Buffer.BlockCopy(value, 0, _votecast, 0, value.Length); }
|
|
}
|
|
}
|
|
public float Majority;
|
|
public int Quorum;
|
|
private byte[] _proposaltext;
|
|
public byte[] ProposalText
|
|
{
|
|
get { return _proposaltext; }
|
|
set
|
|
{
|
|
if (value == null) { _proposaltext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _proposaltext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _proposaltext, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_tersedateid = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _tersedateid, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_startdatetime = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _startdatetime, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_enddatetime = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _enddatetime, 0, length); i += length;
|
|
AlreadyVoted = (bytes[i++] != 0) ? (bool)true : (bool)false;
|
|
length = (ushort)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 = (ushort)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;
|
|
while (
|
|
ProposalDataStart < ProposalData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupVoteHistoryRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 class HistoryItemDataBlock : PacketBlock
|
|
{
|
|
public UUID VoteID;
|
|
private byte[] _tersedateid;
|
|
public byte[] TerseDateID
|
|
{
|
|
get { return _tersedateid; }
|
|
set
|
|
{
|
|
if (value == null) { _tersedateid = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _tersedateid = new byte[value.Length]; Buffer.BlockCopy(value, 0, _tersedateid, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _startdatetime;
|
|
public byte[] StartDateTime
|
|
{
|
|
get { return _startdatetime; }
|
|
set
|
|
{
|
|
if (value == null) { _startdatetime = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _startdatetime = new byte[value.Length]; Buffer.BlockCopy(value, 0, _startdatetime, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _enddatetime;
|
|
public byte[] EndDateTime
|
|
{
|
|
get { return _enddatetime; }
|
|
set
|
|
{
|
|
if (value == null) { _enddatetime = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _enddatetime = new byte[value.Length]; Buffer.BlockCopy(value, 0, _enddatetime, 0, value.Length); }
|
|
}
|
|
}
|
|
public UUID VoteInitiator;
|
|
private byte[] _votetype;
|
|
public byte[] VoteType
|
|
{
|
|
get { return _votetype; }
|
|
set
|
|
{
|
|
if (value == null) { _votetype = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _votetype = new byte[value.Length]; Buffer.BlockCopy(value, 0, _votetype, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _voteresult;
|
|
public byte[] VoteResult
|
|
{
|
|
get { return _voteresult; }
|
|
set
|
|
{
|
|
if (value == null) { _voteresult = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _voteresult = new byte[value.Length]; Buffer.BlockCopy(value, 0, _voteresult, 0, value.Length); }
|
|
}
|
|
}
|
|
public float Majority;
|
|
public int Quorum;
|
|
private byte[] _proposaltext;
|
|
public byte[] ProposalText
|
|
{
|
|
get { return _proposaltext; }
|
|
set
|
|
{
|
|
if (value == null) { _proposaltext = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _proposaltext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _proposaltext, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_tersedateid = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _tersedateid, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_startdatetime = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _startdatetime, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_enddatetime = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _enddatetime, 0, length); i += length;
|
|
VoteInitiator.FromBytes(bytes, i); i += 16;
|
|
length = (ushort)bytes[i++];
|
|
_votetype = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _votetype, 0, length); i += length;
|
|
length = (ushort)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 = (ushort)(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 class VoteItemBlock : PacketBlock
|
|
{
|
|
public UUID CandidateID;
|
|
private byte[] _votecast;
|
|
public byte[] VoteCast
|
|
{
|
|
get { return _votecast; }
|
|
set
|
|
{
|
|
if (value == null) { _votecast = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _votecast = new byte[value.Length]; Buffer.BlockCopy(value, 0, _votecast, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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;
|
|
while (
|
|
VoteItemStart < VoteItem.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StartGroupProposalPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ProposalDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public int Quorum;
|
|
public float Majority;
|
|
public int Duration;
|
|
private byte[] _proposaltext;
|
|
public byte[] ProposalText
|
|
{
|
|
get { return _proposaltext; }
|
|
set
|
|
{
|
|
if (value == null) { _proposaltext = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _proposaltext = new byte[value.Length]; Buffer.BlockCopy(value, 0, _proposaltext, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 class ProposalDataBlock : PacketBlock
|
|
{
|
|
public UUID ProposalID;
|
|
public UUID GroupID;
|
|
private byte[] _votecast;
|
|
public byte[] VoteCast
|
|
{
|
|
get { return _votecast; }
|
|
set
|
|
{
|
|
if (value == null) { _votecast = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _votecast = new byte[value.Length]; Buffer.BlockCopy(value, 0, _votecast, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 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 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 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 class MemberDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public int Contribution;
|
|
private byte[] _onlinestatus;
|
|
public byte[] OnlineStatus
|
|
{
|
|
get { return _onlinestatus; }
|
|
set
|
|
{
|
|
if (value == null) { _onlinestatus = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _onlinestatus = new byte[value.Length]; Buffer.BlockCopy(value, 0, _onlinestatus, 0, value.Length); }
|
|
}
|
|
}
|
|
public ulong AgentPowers;
|
|
private byte[] _title;
|
|
public byte[] Title
|
|
{
|
|
get { return _title; }
|
|
set
|
|
{
|
|
if (value == null) { _title = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _title = new byte[value.Length]; Buffer.BlockCopy(value, 0, _title, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 = (ushort)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;
|
|
while (
|
|
MemberDataStart < MemberData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ActivateGroupPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 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 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 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 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 class RoleDataBlock : PacketBlock
|
|
{
|
|
public UUID RoleID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _title;
|
|
public byte[] Title
|
|
{
|
|
get { return _title; }
|
|
set
|
|
{
|
|
if (value == null) { _title = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _title = new byte[value.Length]; Buffer.BlockCopy(value, 0, _title, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_title = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _title, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
RoleDataStart < RoleData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupRoleMembersRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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;
|
|
while (
|
|
MemberDataStart < MemberData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupTitlesRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 class GroupDataBlock : PacketBlock
|
|
{
|
|
private byte[] _title;
|
|
public byte[] Title
|
|
{
|
|
get { return _title; }
|
|
set
|
|
{
|
|
if (value == null) { _title = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _title = new byte[value.Length]; Buffer.BlockCopy(value, 0, _title, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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;
|
|
while (
|
|
GroupDataStart < GroupData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class GroupTitleUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 class RoleDataBlock : PacketBlock
|
|
{
|
|
public UUID RoleID;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _title;
|
|
public byte[] Title
|
|
{
|
|
get { return _title; }
|
|
set
|
|
{
|
|
if (value == null) { _title = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _title = new byte[value.Length]; Buffer.BlockCopy(value, 0, _title, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _description, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
RoleDataStart < RoleData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LiveHelpGroupRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ReplyDataBlock : PacketBlock
|
|
{
|
|
public UUID RequestID;
|
|
public UUID GroupID;
|
|
private byte[] _selection;
|
|
public byte[] Selection
|
|
{
|
|
get { return _selection; }
|
|
set
|
|
{
|
|
if (value == null) { _selection = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _selection = new byte[value.Length]; Buffer.BlockCopy(value, 0, _selection, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 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 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;
|
|
while (
|
|
WearableDataStart < WearableData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentIsNowWearingPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
WearableDataStart < WearableData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentCachedTexturePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
WearableDataStart < WearableData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentCachedTextureResponsePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class WearableDataBlock : PacketBlock
|
|
{
|
|
public UUID TextureID;
|
|
public byte TextureIndex;
|
|
private byte[] _hostname;
|
|
public byte[] HostName
|
|
{
|
|
get { return _hostname; }
|
|
set
|
|
{
|
|
if (value == null) { _hostname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _hostname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _hostname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
WearableDataStart < WearableData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDataUpdateRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
private byte[] _firstname;
|
|
public byte[] FirstName
|
|
{
|
|
get { return _firstname; }
|
|
set
|
|
{
|
|
if (value == null) { _firstname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _firstname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _firstname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _lastname;
|
|
public byte[] LastName
|
|
{
|
|
get { return _lastname; }
|
|
set
|
|
{
|
|
if (value == null) { _lastname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _lastname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _lastname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _grouptitle;
|
|
public byte[] GroupTitle
|
|
{
|
|
get { return _grouptitle; }
|
|
set
|
|
{
|
|
if (value == null) { _grouptitle = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _grouptitle = new byte[value.Length]; Buffer.BlockCopy(value, 0, _grouptitle, 0, value.Length); }
|
|
}
|
|
}
|
|
public UUID ActiveGroupID;
|
|
public ulong GroupPowers;
|
|
private byte[] _groupname;
|
|
public byte[] GroupName
|
|
{
|
|
get { return _groupname; }
|
|
set
|
|
{
|
|
if (value == null) { _groupname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _groupname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _groupname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_firstname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _firstname, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_lastname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _lastname, 0, length); i += length;
|
|
length = (ushort)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 = (ushort)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 class AgentGroupDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID GroupID;
|
|
public ulong AgentPowers;
|
|
private byte[] _grouptitle;
|
|
public byte[] GroupTitle
|
|
{
|
|
get { return _grouptitle; }
|
|
set
|
|
{
|
|
if (value == null) { _grouptitle = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _grouptitle = new byte[value.Length]; Buffer.BlockCopy(value, 0, _grouptitle, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
AgentGroupDataStart < AgentGroupData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentGroupDataUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class GroupDataBlock : PacketBlock
|
|
{
|
|
public UUID GroupID;
|
|
public ulong GroupPowers;
|
|
public bool AcceptNotices;
|
|
public UUID GroupInsigniaID;
|
|
public int Contribution;
|
|
private byte[] _groupname;
|
|
public byte[] GroupName
|
|
{
|
|
get { return _groupname; }
|
|
set
|
|
{
|
|
if (value == null) { _groupname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _groupname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _groupname, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
GroupDataStart < GroupData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentDropGroupPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 CreateTrustedCircuitPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class DataBlockBlock : PacketBlock
|
|
{
|
|
public UUID EndPointID;
|
|
public byte[] Digest;
|
|
|
|
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
|
|
{
|
|
EndPointID.FromBytes(bytes, i); i += 16;
|
|
Digest = new byte[32];
|
|
Buffer.BlockCopy(bytes, i, Digest, 0, 32); i += 32;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
EndPointID.ToBytes(bytes, i); i += 16;
|
|
Buffer.BlockCopy(Digest, 0, bytes, i, 32);i += 32;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += DataBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlockBlock DataBlock;
|
|
|
|
public CreateTrustedCircuitPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.CreateTrustedCircuit;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 392;
|
|
Header.Reliable = true;
|
|
DataBlock = new DataBlockBlock();
|
|
}
|
|
|
|
public CreateTrustedCircuitPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, 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 CreateTrustedCircuitPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 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 = 10;
|
|
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 DenyTrustedCircuitPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class DataBlockBlock : PacketBlock
|
|
{
|
|
public UUID EndPointID;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
return 16;
|
|
}
|
|
}
|
|
|
|
public DataBlockBlock() { }
|
|
public DataBlockBlock(byte[] bytes, ref int i)
|
|
{
|
|
FromBytes(bytes, ref i);
|
|
}
|
|
|
|
public override void FromBytes(byte[] bytes, ref int i)
|
|
{
|
|
try
|
|
{
|
|
EndPointID.FromBytes(bytes, i); i += 16;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new MalformedDataException();
|
|
}
|
|
}
|
|
|
|
public override void ToBytes(byte[] bytes, ref int i)
|
|
{
|
|
EndPointID.ToBytes(bytes, i); i += 16;
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
length += DataBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public DataBlockBlock DataBlock;
|
|
|
|
public DenyTrustedCircuitPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.DenyTrustedCircuit;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 393;
|
|
Header.Reliable = true;
|
|
DataBlock = new DataBlockBlock();
|
|
}
|
|
|
|
public DenyTrustedCircuitPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, 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 DenyTrustedCircuitPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 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 = 10;
|
|
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 RequestTrustedCircuitPacket : Packet
|
|
{
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 10;
|
|
return length;
|
|
}
|
|
}
|
|
|
|
public RequestTrustedCircuitPacket()
|
|
{
|
|
HasVariableBlocks = false;
|
|
Type = PacketType.RequestTrustedCircuit;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 394;
|
|
Header.Reliable = true;
|
|
}
|
|
|
|
public RequestTrustedCircuitPacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, 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 RequestTrustedCircuitPacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 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 RezSingleAttachmentFromInvPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID OwnerID;
|
|
public byte AttachmentPt;
|
|
public uint ItemFlags;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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 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 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
public UUID ItemID;
|
|
public UUID OwnerID;
|
|
public byte AttachmentPt;
|
|
public uint ItemFlags;
|
|
public uint GroupMask;
|
|
public uint EveryoneMask;
|
|
public uint NextOwnerMask;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class DetachAttachmentIntoInvPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class UserInfoRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 class UserDataBlock : PacketBlock
|
|
{
|
|
public bool IMViaEMail;
|
|
private byte[] _directoryvisibility;
|
|
public byte[] DirectoryVisibility
|
|
{
|
|
get { return _directoryvisibility; }
|
|
set
|
|
{
|
|
if (value == null) { _directoryvisibility = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _directoryvisibility = new byte[value.Length]; Buffer.BlockCopy(value, 0, _directoryvisibility, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _email;
|
|
public byte[] EMail
|
|
{
|
|
get { return _email; }
|
|
set
|
|
{
|
|
if (value == null) { _email = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _email = new byte[value.Length]; Buffer.BlockCopy(value, 0, _email, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_directoryvisibility = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _directoryvisibility, 0, length); i += length;
|
|
length = (ushort)(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 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 class UserDataBlock : PacketBlock
|
|
{
|
|
public bool IMViaEMail;
|
|
private byte[] _directoryvisibility;
|
|
public byte[] DirectoryVisibility
|
|
{
|
|
get { return _directoryvisibility; }
|
|
set
|
|
{
|
|
if (value == null) { _directoryvisibility = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _directoryvisibility = new byte[value.Length]; Buffer.BlockCopy(value, 0, _directoryvisibility, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 class FileDataBlock : PacketBlock
|
|
{
|
|
private byte[] _simfilename;
|
|
public byte[] SimFilename
|
|
{
|
|
get { return _simfilename; }
|
|
set
|
|
{
|
|
if (value == null) { _simfilename = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _simfilename = new byte[value.Length]; Buffer.BlockCopy(value, 0, _simfilename, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _viewerfilename;
|
|
public byte[] ViewerFilename
|
|
{
|
|
get { return _viewerfilename; }
|
|
set
|
|
{
|
|
if (value == null) { _viewerfilename = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _viewerfilename = new byte[value.Length]; Buffer.BlockCopy(value, 0, _viewerfilename, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_simfilename = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _simfilename, 0, length); i += length;
|
|
length = (ushort)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 SystemMessagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class MethodDataBlock : PacketBlock
|
|
{
|
|
private byte[] _method;
|
|
public byte[] Method
|
|
{
|
|
get { return _method; }
|
|
set
|
|
{
|
|
if (value == null) { _method = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _method = new byte[value.Length]; Buffer.BlockCopy(value, 0, _method, 0, value.Length); }
|
|
}
|
|
}
|
|
public UUID Invoice;
|
|
public byte[] Digest;
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 49;
|
|
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 = (ushort)bytes[i++];
|
|
_method = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _method, 0, length); i += length;
|
|
Invoice.FromBytes(bytes, i); i += 16;
|
|
Digest = new byte[32];
|
|
Buffer.BlockCopy(bytes, i, Digest, 0, 32); i += 32;
|
|
}
|
|
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;
|
|
Buffer.BlockCopy(Digest, 0, bytes, i, 32);i += 32;
|
|
}
|
|
|
|
}
|
|
|
|
/// <exclude/>
|
|
public class ParamListBlock : PacketBlock
|
|
{
|
|
private byte[] _parameter;
|
|
public byte[] Parameter
|
|
{
|
|
get { return _parameter; }
|
|
set
|
|
{
|
|
if (value == null) { _parameter = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _parameter = new byte[value.Length]; Buffer.BlockCopy(value, 0, _parameter, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 += MethodData.Length;
|
|
for (int j = 0; j < ParamList.Length; j++)
|
|
length += ParamList[j].Length;
|
|
return length;
|
|
}
|
|
}
|
|
public MethodDataBlock MethodData;
|
|
public ParamListBlock[] ParamList;
|
|
|
|
public SystemMessagePacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.SystemMessage;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 404;
|
|
Header.Reliable = true;
|
|
Header.Zerocoded = true;
|
|
MethodData = new MethodDataBlock();
|
|
ParamList = null;
|
|
}
|
|
|
|
public SystemMessagePacket(byte[] bytes, ref int i) : this()
|
|
{
|
|
int packetEnd = bytes.Length - 1;
|
|
FromBytes(bytes, ref i, ref packetEnd, null);
|
|
}
|
|
|
|
override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, 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);
|
|
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 SystemMessagePacket(Header head, byte[] bytes, ref int i): this()
|
|
{
|
|
int packetEnd = bytes.Length - 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);
|
|
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 += 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);
|
|
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 += MethodData.Length;
|
|
byte[] fixedBytes = new byte[fixedLength];
|
|
Header.ToBytes(fixedBytes, ref i);
|
|
MethodData.ToBytes(fixedBytes, ref i);
|
|
fixedLength += 1;
|
|
|
|
int ParamListStart = 0;
|
|
while (
|
|
ParamListStart < ParamList.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MapLayerRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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;
|
|
while (
|
|
LayerDataStart < LayerData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MapBlockRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class NameDataBlock : PacketBlock
|
|
{
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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 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 class DataBlock : PacketBlock
|
|
{
|
|
public ushort X;
|
|
public ushort Y;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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;
|
|
}
|
|
|
|
}
|
|
|
|
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 MapBlockReplyPacket()
|
|
{
|
|
HasVariableBlocks = true;
|
|
Type = PacketType.MapBlockReply;
|
|
Header = new Header();
|
|
Header.Frequency = PacketFrequency.Low;
|
|
Header.ID = 409;
|
|
Header.Reliable = true;
|
|
AgentData = new AgentDataBlock();
|
|
Data = 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); }
|
|
}
|
|
|
|
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); }
|
|
}
|
|
|
|
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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class MapItemRequestPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 class DataBlock : PacketBlock
|
|
{
|
|
public uint X;
|
|
public uint Y;
|
|
public UUID ID;
|
|
public int Extra;
|
|
public int Extra2;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
DataStart < Data.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SendPostcardPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class AgentDataBlock : PacketBlock
|
|
{
|
|
public UUID AgentID;
|
|
public UUID SessionID;
|
|
public UUID AssetID;
|
|
public Vector3d PosGlobal;
|
|
private byte[] _to;
|
|
public byte[] To
|
|
{
|
|
get { return _to; }
|
|
set
|
|
{
|
|
if (value == null) { _to = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _to = new byte[value.Length]; Buffer.BlockCopy(value, 0, _to, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _from;
|
|
public byte[] From
|
|
{
|
|
get { return _from; }
|
|
set
|
|
{
|
|
if (value == null) { _from = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _from = new byte[value.Length]; Buffer.BlockCopy(value, 0, _from, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _subject;
|
|
public byte[] Subject
|
|
{
|
|
get { return _subject; }
|
|
set
|
|
{
|
|
if (value == null) { _subject = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _subject = new byte[value.Length]; Buffer.BlockCopy(value, 0, _subject, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _msg;
|
|
public byte[] Msg
|
|
{
|
|
get { return _msg; }
|
|
set
|
|
{
|
|
if (value == null) { _msg = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _msg = new byte[value.Length]; Buffer.BlockCopy(value, 0, _msg, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_to = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _to, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_from = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _from, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_subject = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _subject, 0, length); i += length;
|
|
length = (ushort)(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 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 class DataBlockBlock : PacketBlock
|
|
{
|
|
private byte[] _mediaurl;
|
|
public byte[] MediaURL
|
|
{
|
|
get { return _mediaurl; }
|
|
set
|
|
{
|
|
if (value == null) { _mediaurl = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _mediaurl = new byte[value.Length]; Buffer.BlockCopy(value, 0, _mediaurl, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 class DataBlockExtendedBlock : PacketBlock
|
|
{
|
|
private byte[] _mediatype;
|
|
public byte[] MediaType
|
|
{
|
|
get { return _mediatype; }
|
|
set
|
|
{
|
|
if (value == null) { _mediatype = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _mediatype = new byte[value.Length]; Buffer.BlockCopy(value, 0, _mediatype, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _mediadesc;
|
|
public byte[] MediaDesc
|
|
{
|
|
get { return _mediadesc; }
|
|
set
|
|
{
|
|
if (value == null) { _mediadesc = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _mediadesc = new byte[value.Length]; Buffer.BlockCopy(value, 0, _mediadesc, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_mediatype = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _mediatype, 0, length); i += length;
|
|
length = (ushort)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 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 class RequestDataBlock : PacketBlock
|
|
{
|
|
public uint ReportType;
|
|
public uint RequestFlags;
|
|
private byte[] _filter;
|
|
public byte[] Filter
|
|
{
|
|
get { return _filter; }
|
|
set
|
|
{
|
|
if (value == null) { _filter = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _filter = new byte[value.Length]; Buffer.BlockCopy(value, 0, _filter, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 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 class ReportDataBlock : PacketBlock
|
|
{
|
|
public uint TaskLocalID;
|
|
public UUID TaskID;
|
|
public float LocationX;
|
|
public float LocationY;
|
|
public float LocationZ;
|
|
public float Score;
|
|
private byte[] _taskname;
|
|
public byte[] TaskName
|
|
{
|
|
get { return _taskname; }
|
|
set
|
|
{
|
|
if (value == null) { _taskname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _taskname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _taskname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _ownername;
|
|
public byte[] OwnerName
|
|
{
|
|
get { return _ownername; }
|
|
set
|
|
{
|
|
if (value == null) { _ownername = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _ownername = new byte[value.Length]; Buffer.BlockCopy(value, 0, _ownername, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_taskname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _taskname, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
ReportDataStart < ReportData.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ErrorPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class DataBlock : PacketBlock
|
|
{
|
|
public int Code;
|
|
private byte[] _token;
|
|
public byte[] Token
|
|
{
|
|
get { return _token; }
|
|
set
|
|
{
|
|
if (value == null) { _token = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _token = new byte[value.Length]; Buffer.BlockCopy(value, 0, _token, 0, value.Length); }
|
|
}
|
|
}
|
|
public UUID ID;
|
|
private byte[] _system;
|
|
public byte[] System
|
|
{
|
|
get { return _system; }
|
|
set
|
|
{
|
|
if (value == null) { _system = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _system = new byte[value.Length]; Buffer.BlockCopy(value, 0, _system, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _message;
|
|
public byte[] Message
|
|
{
|
|
get { return _message; }
|
|
set
|
|
{
|
|
if (value == null) { _message = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _message = new byte[value.Length]; Buffer.BlockCopy(value, 0, _message, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_token = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _token, 0, length); i += length;
|
|
ID.FromBytes(bytes, i); i += 16;
|
|
length = (ushort)bytes[i++];
|
|
_system = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _system, 0, length); i += length;
|
|
length = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
_message = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _message, 0, length); i += length;
|
|
length = (ushort)(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 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RezRestoreToWorldPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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 PacketAckPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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;
|
|
while (
|
|
PacketsStart < Packets.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class OpenCircuitPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint ObjectLocalID;
|
|
public byte Type;
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestMultipleObjectsPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectPositionPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestObjectPropertiesFamilyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 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 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 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 class RegionDataBlock : PacketBlock
|
|
{
|
|
public uint SimIP;
|
|
public ushort SimPort;
|
|
public ulong RegionHandle;
|
|
private byte[] _seedcapability;
|
|
public byte[] SeedCapability
|
|
{
|
|
get { return _seedcapability; }
|
|
set
|
|
{
|
|
if (value == null) { _seedcapability = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _seedcapability = new byte[value.Length]; Buffer.BlockCopy(value, 0, _seedcapability, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 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 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _touchname;
|
|
public byte[] TouchName
|
|
{
|
|
get { return _touchname; }
|
|
set
|
|
{
|
|
if (value == null) { _touchname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _touchname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _touchname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _sitname;
|
|
public byte[] SitName
|
|
{
|
|
get { return _sitname; }
|
|
set
|
|
{
|
|
if (value == null) { _sitname = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _sitname = new byte[value.Length]; Buffer.BlockCopy(value, 0, _sitname, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _textureid;
|
|
public byte[] TextureID
|
|
{
|
|
get { return _textureid; }
|
|
set
|
|
{
|
|
if (value == null) { _textureid = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _textureid = new byte[value.Length]; Buffer.BlockCopy(value, 0, _textureid, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_description = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _description, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_touchname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _touchname, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_sitname = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _sitname, 0, length); i += length;
|
|
length = (ushort)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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectPropertiesFamilyPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _description;
|
|
public byte[] Description
|
|
{
|
|
get { return _description; }
|
|
set
|
|
{
|
|
if (value == null) { _description = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _description = new byte[value.Length]; Buffer.BlockCopy(value, 0, _description, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)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 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 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 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 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 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;
|
|
while (
|
|
DataBlockStart < DataBlock.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ViewerEffectPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class EffectBlock : PacketBlock
|
|
{
|
|
public UUID ID;
|
|
public UUID AgentID;
|
|
public byte Type;
|
|
public float Duration;
|
|
public byte[] Color;
|
|
private byte[] _typedata;
|
|
public byte[] TypeData
|
|
{
|
|
get { return _typedata; }
|
|
set
|
|
{
|
|
if (value == null) { _typedata = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _typedata = new byte[value.Length]; Buffer.BlockCopy(value, 0, _typedata, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
EffectStart < Effect.Length)
|
|
{
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class StartPingCheckPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CompletePingCheckPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentAnimationPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 class PhysicalAvatarEventListBlock : PacketBlock
|
|
{
|
|
private byte[] _typedata;
|
|
public byte[] TypeData
|
|
{
|
|
get { return _typedata; }
|
|
set
|
|
{
|
|
if (value == null) { _typedata = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _typedata = new byte[value.Length]; Buffer.BlockCopy(value, 0, _typedata, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
AnimationListStart < AnimationList.Length ||
|
|
PhysicalAvatarEventListStart < PhysicalAvatarEventList.Length)
|
|
{
|
|
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 = 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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentRequestSitPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AgentSitPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class RequestImagePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
RequestImageStart < RequestImage.Length)
|
|
{
|
|
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 = 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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImageDataPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ImageDataBlock : PacketBlock
|
|
{
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImagePacketPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ImageDataBlock : PacketBlock
|
|
{
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class LayerDataPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class LayerDataBlock : PacketBlock
|
|
{
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
private byte[] _objectdata;
|
|
public byte[] ObjectData
|
|
{
|
|
get { return _objectdata; }
|
|
set
|
|
{
|
|
if (value == null) { _objectdata = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _objectdata = new byte[value.Length]; Buffer.BlockCopy(value, 0, _objectdata, 0, value.Length); }
|
|
}
|
|
}
|
|
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;
|
|
private byte[] _textureentry;
|
|
public byte[] TextureEntry
|
|
{
|
|
get { return _textureentry; }
|
|
set
|
|
{
|
|
if (value == null) { _textureentry = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _textureentry = new byte[value.Length]; Buffer.BlockCopy(value, 0, _textureentry, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _textureanim;
|
|
public byte[] TextureAnim
|
|
{
|
|
get { return _textureanim; }
|
|
set
|
|
{
|
|
if (value == null) { _textureanim = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _textureanim = new byte[value.Length]; Buffer.BlockCopy(value, 0, _textureanim, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _namevalue;
|
|
public byte[] NameValue
|
|
{
|
|
get { return _namevalue; }
|
|
set
|
|
{
|
|
if (value == null) { _namevalue = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _namevalue = new byte[value.Length]; Buffer.BlockCopy(value, 0, _namevalue, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _text;
|
|
public byte[] Text
|
|
{
|
|
get { return _text; }
|
|
set
|
|
{
|
|
if (value == null) { _text = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _text = new byte[value.Length]; Buffer.BlockCopy(value, 0, _text, 0, value.Length); }
|
|
}
|
|
}
|
|
public byte[] TextColor;
|
|
private byte[] _mediaurl;
|
|
public byte[] MediaURL
|
|
{
|
|
get { return _mediaurl; }
|
|
set
|
|
{
|
|
if (value == null) { _mediaurl = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _mediaurl = new byte[value.Length]; Buffer.BlockCopy(value, 0, _mediaurl, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _psblock;
|
|
public byte[] PSBlock
|
|
{
|
|
get { return _psblock; }
|
|
set
|
|
{
|
|
if (value == null) { _psblock = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _psblock = new byte[value.Length]; Buffer.BlockCopy(value, 0, _psblock, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _extraparams;
|
|
public byte[] ExtraParams
|
|
{
|
|
get { return _extraparams; }
|
|
set
|
|
{
|
|
if (value == null) { _extraparams = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _extraparams = new byte[value.Length]; Buffer.BlockCopy(value, 0, _extraparams, 0, value.Length); }
|
|
}
|
|
}
|
|
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 += ObjectData.Length; }
|
|
if (TextureEntry != null) { length += TextureEntry.Length; }
|
|
if (TextureAnim != null) { length += TextureAnim.Length; }
|
|
if (NameValue != null) { length += NameValue.Length; }
|
|
if (Data != null) { length += Data.Length; }
|
|
if (Text != null) { length += Text.Length; }
|
|
if (MediaURL != null) { length += MediaURL.Length; }
|
|
if (PSBlock != null) { length += PSBlock.Length; }
|
|
if (ExtraParams != null) { length += 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 = (ushort)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 = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
_textureentry = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _textureentry, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_textureanim = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _textureanim, 0, length); i += length;
|
|
length = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
_namevalue = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _namevalue, 0, length); i += length;
|
|
length = (ushort)(bytes[i++] + (bytes[i++] << 8));
|
|
_data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _data, 0, length); i += length;
|
|
length = (ushort)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 = (ushort)bytes[i++];
|
|
_mediaurl = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _mediaurl, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_psblock = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _psblock, 0, length); i += length;
|
|
length = (ushort)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, ObjectData.Length); i += 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);
|
|
bytes[i++] = (byte)(TextureEntry.Length % 256);
|
|
bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256);
|
|
Buffer.BlockCopy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length;
|
|
bytes[i++] = (byte)TextureAnim.Length;
|
|
Buffer.BlockCopy(TextureAnim, 0, bytes, i, TextureAnim.Length); i += TextureAnim.Length;
|
|
bytes[i++] = (byte)(NameValue.Length % 256);
|
|
bytes[i++] = (byte)((NameValue.Length >> 8) % 256);
|
|
Buffer.BlockCopy(NameValue, 0, bytes, i, NameValue.Length); i += NameValue.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;
|
|
bytes[i++] = (byte)Text.Length;
|
|
Buffer.BlockCopy(Text, 0, bytes, i, Text.Length); i += Text.Length;
|
|
Buffer.BlockCopy(TextColor, 0, bytes, i, 4);i += 4;
|
|
bytes[i++] = (byte)MediaURL.Length;
|
|
Buffer.BlockCopy(MediaURL, 0, bytes, i, MediaURL.Length); i += MediaURL.Length;
|
|
bytes[i++] = (byte)PSBlock.Length;
|
|
Buffer.BlockCopy(PSBlock, 0, bytes, i, PSBlock.Length); i += PSBlock.Length;
|
|
bytes[i++] = (byte)ExtraParams.Length;
|
|
Buffer.BlockCopy(ExtraParams, 0, bytes, i, ExtraParams.Length); i += ExtraParams.Length;
|
|
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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectUpdateCompressedPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
public uint UpdateFlags;
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ObjectUpdateCachedPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ImprovedTerseObjectUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class ObjectDataBlock : PacketBlock
|
|
{
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _textureentry;
|
|
public byte[] TextureEntry
|
|
{
|
|
get { return _textureentry; }
|
|
set
|
|
{
|
|
if (value == null) { _textureentry = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _textureentry = new byte[value.Length]; Buffer.BlockCopy(value, 0, _textureentry, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)bytes[i++];
|
|
_data = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _data, 0, length); i += length;
|
|
length = (ushort)(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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class KillObjectPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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;
|
|
while (
|
|
ObjectDataStart < ObjectData.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class TransferPacketPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public class TransferDataBlock : PacketBlock
|
|
{
|
|
public UUID TransferID;
|
|
public int ChannelType;
|
|
public int Packet;
|
|
public int Status;
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SendXferPacketPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 class DataPacketBlock : PacketBlock
|
|
{
|
|
private byte[] _data;
|
|
public byte[] Data
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
if (value == null) { _data = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _data = new byte[value.Length]; Buffer.BlockCopy(value, 0, _data, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ConfirmXferPacketPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarAnimationPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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 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 class PhysicalAvatarEventListBlock : PacketBlock
|
|
{
|
|
private byte[] _typedata;
|
|
public byte[] TypeData
|
|
{
|
|
get { return _typedata; }
|
|
set
|
|
{
|
|
if (value == null) { _typedata = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _typedata = new byte[value.Length]; Buffer.BlockCopy(value, 0, _typedata, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)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;
|
|
while (
|
|
AnimationListStart < AnimationList.Length ||
|
|
AnimationSourceListStart < AnimationSourceList.Length ||
|
|
PhysicalAvatarEventListStart < PhysicalAvatarEventList.Length)
|
|
{
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class AvatarSitResponsePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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 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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class CameraConstraintPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ParcelPropertiesPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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;
|
|
private byte[] _bitmap;
|
|
public byte[] Bitmap
|
|
{
|
|
get { return _bitmap; }
|
|
set
|
|
{
|
|
if (value == null) { _bitmap = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _bitmap = new byte[value.Length]; Buffer.BlockCopy(value, 0, _bitmap, 0, value.Length); }
|
|
}
|
|
}
|
|
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;
|
|
private byte[] _name;
|
|
public byte[] Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (value == null) { _name = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _name = new byte[value.Length]; Buffer.BlockCopy(value, 0, _name, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _desc;
|
|
public byte[] Desc
|
|
{
|
|
get { return _desc; }
|
|
set
|
|
{
|
|
if (value == null) { _desc = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _desc = new byte[value.Length]; Buffer.BlockCopy(value, 0, _desc, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _musicurl;
|
|
public byte[] MusicURL
|
|
{
|
|
get { return _musicurl; }
|
|
set
|
|
{
|
|
if (value == null) { _musicurl = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _musicurl = new byte[value.Length]; Buffer.BlockCopy(value, 0, _musicurl, 0, value.Length); }
|
|
}
|
|
}
|
|
private byte[] _mediaurl;
|
|
public byte[] MediaURL
|
|
{
|
|
get { return _mediaurl; }
|
|
set
|
|
{
|
|
if (value == null) { _mediaurl = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _mediaurl = new byte[value.Length]; Buffer.BlockCopy(value, 0, _mediaurl, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)(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 = (ushort)bytes[i++];
|
|
_name = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _name, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_desc = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _desc, 0, length); i += length;
|
|
length = (ushort)bytes[i++];
|
|
_musicurl = new byte[length];
|
|
Buffer.BlockCopy(bytes, i, _musicurl, 0, length); i += length;
|
|
length = (ushort)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 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);
|
|
}
|
|
|
|
}
|
|
|
|
public override int Length
|
|
{
|
|
get
|
|
{
|
|
int length = 7;
|
|
length += ParcelData.Length;
|
|
length += AgeVerificationBlock.Length;
|
|
return length;
|
|
}
|
|
}
|
|
public ParcelDataBlock ParcelData;
|
|
public AgeVerificationBlockBlock AgeVerificationBlock;
|
|
|
|
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();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public override byte[] ToBytes()
|
|
{
|
|
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 = new byte[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); }
|
|
return bytes;
|
|
}
|
|
|
|
public override byte[][] ToBytesMultiple()
|
|
{
|
|
return new byte[][] { ToBytes() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChildAgentUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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;
|
|
private byte[] _throttles;
|
|
public byte[] Throttles
|
|
{
|
|
get { return _throttles; }
|
|
set
|
|
{
|
|
if (value == null) { _throttles = null; return; }
|
|
if (value.Length > 255) { throw new OverflowException("Value exceeds 255 characters"); }
|
|
else { _throttles = new byte[value.Length]; Buffer.BlockCopy(value, 0, _throttles, 0, value.Length); }
|
|
}
|
|
}
|
|
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;
|
|
private byte[] _agenttextures;
|
|
public byte[] AgentTextures
|
|
{
|
|
get { return _agenttextures; }
|
|
set
|
|
{
|
|
if (value == null) { _agenttextures = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _agenttextures = new byte[value.Length]; Buffer.BlockCopy(value, 0, _agenttextures, 0, value.Length); }
|
|
}
|
|
}
|
|
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 = (ushort)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 = (ushort)(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 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 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 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 class NVPairDataBlock : PacketBlock
|
|
{
|
|
private byte[] _nvpairs;
|
|
public byte[] NVPairs
|
|
{
|
|
get { return _nvpairs; }
|
|
set
|
|
{
|
|
if (value == null) { _nvpairs = null; return; }
|
|
if (value.Length > 1100) { throw new OverflowException("Value exceeds 1100 characters"); }
|
|
else { _nvpairs = new byte[value.Length]; Buffer.BlockCopy(value, 0, _nvpairs, 0, value.Length); }
|
|
}
|
|
}
|
|
|
|
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 = (ushort)(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 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 < 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;
|
|
return length;
|
|
}
|
|
}
|
|
public AgentDataBlock AgentData;
|
|
public GroupDataBlock[] GroupData;
|
|
public AnimationDataBlock[] AnimationData;
|
|
public GranterBlockBlock[] GranterBlock;
|
|
public NVPairDataBlock[] NVPairData;
|
|
public VisualParamBlock[] VisualParam;
|
|
|
|
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;
|
|
}
|
|
|
|
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); }
|
|
}
|
|
|
|
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); }
|
|
}
|
|
|
|
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; }
|
|
if (Header.AckList != null && Header.AckList.Length > 0) { 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); }
|
|
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 += 5;
|
|
|
|
int GroupDataStart = 0;
|
|
int AnimationDataStart = 0;
|
|
int GranterBlockStart = 0;
|
|
int NVPairDataStart = 0;
|
|
int VisualParamStart = 0;
|
|
while (
|
|
GroupDataStart < GroupData.Length ||
|
|
AnimationDataStart < AnimationData.Length ||
|
|
GranterBlockStart < GranterBlock.Length ||
|
|
NVPairDataStart < NVPairData.Length ||
|
|
VisualParamStart < VisualParam.Length)
|
|
{
|
|
int variableLength = 0;
|
|
int GroupDataCount = 0;
|
|
int AnimationDataCount = 0;
|
|
int GranterBlockCount = 0;
|
|
int NVPairDataCount = 0;
|
|
int VisualParamCount = 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;
|
|
}
|
|
|
|
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;
|
|
|
|
if (acksLength > 0) {
|
|
Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);
|
|
acksLength = 0;
|
|
}
|
|
|
|
packets.Add(packet);
|
|
}
|
|
|
|
return packets.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChildAgentAlivePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class ChildAgentPositionUpdatePacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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() };
|
|
}
|
|
}
|
|
|
|
/// <exclude/>
|
|
public sealed class SoundTriggerPacket : Packet
|
|
{
|
|
/// <exclude/>
|
|
public 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() };
|
|
}
|
|
}
|
|
|
|
}
|