KPD

Kogama Packet Decoder

Este script não deve ser instalado diretamente. Este script é uma biblioteca de outros scripts para incluir com o diretório meta // @require https://update.greasyfork.org/scripts/441869/1034053/KPD.js

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

You will need to install an extension such as Tampermonkey to install this script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name        KPD
// @license     MIT
// @version     1.1
// @description Kogama Packet Decoder
// @author      0vC4
// @namespace   https://greasyfork.org/users/670183
// @match       http://*/*
// @match       https://*/*
// @grant       none
// @run-at      document-start
// ==/UserScript==





const KPD = (() => {
	const code2type = code => Object.fromEntries(Object.entries(code).map(a=>a.reverse()));

	const PhotonCode = {ClientKey:1,ModeKey:2,ServerKey:1,InitEncryption:0,Ping:1,Ok:0};
	const MVOpCode = {RegisterWorldObject:0,UnregisterWorldObject:1,UpdateWorldObject:2,UpdateWorldObjectData:3,UpdateWorldObjectDataPartial:4,RemoveWorldObjectDataPartial:5,TransferOwnership:6,UpdatePrototype:7,UpdatePrototypeScale:8,AddLink:9,RemoveLink:10,PublishPlanet:11,AddPrototypeToInventory:12,RemoveItemFromInventory:13,UpdateInventorySlots:14,RequestFriendshipByProfileId:15,RequestAcceptFriendship:16,RequestRejectFriendship:17,TriggerBoxEnter:18,TriggerBoxExit:19,LockHierarchy:20,UploadScreenshot:21,RequestWoUniquePrototype:22,ReportCaptureFlag:23,ResetLogicChunk:24,UpdateWorldObjectRunTimeData:25,UpdateLineOfFire:26,WorldObjectRPCOperation:27,PostGameMsg:28,SetTeam:29,AddObjectLink:30,RemoveObjectLink:31,TransferWorldObjectsToGroup:32,CloneWorldObjectTree:33,AddPlanetToPlanet:34,PurchaseProduct:35,GetNextGameBatch:36,RequestBuiltInItem:37,AddItemToWorld:38,AddWorldObjectToInventory:39,AddWorldObjectToInventoryDev:40,SetActiveAvatar:41,ResetAvatar:42,GetMarketPlaceItem:43,AddItemToMarketPlace:44,RemoveItemFromMarketPlace:45,SetAvatarAccessorySlot:46,AttachWorldObjectToSeat:47,DetachWorldObjectFromVehicle:48,SpawnVehicleWithDriver:49,ClientLog:50,UpdateAvatarAccessoryOffset:51,RuntimeEvent:52,ResetTerrain:53,AddAvatarToAvatarShopInventory:54,DeleteAvatarFromShopInventory:55,LevelChanged:56,Ban:57,Syncronize:58,SwitchAvatar:59,SyncronizePing:60,JoinNotification:61,UploadBytes:62,Notification:63,CloneWorldObjectTreeWithPosition:64,CloneTempWorldObjectWithOriginalReference:65,LogicActivateRequest:66,AdminOperation:67,OwnerOperation:68,ResetFirstTimeEvents:83,SetFirstTimeEvent:84,OverrideFirstTimeEvent:85,GetResetAvatar:86,ClaimPlayingNewGameRewardedGold:87,PostChatMsg:88,SetSayChatBubbleVisible:93,ReportReachedTimeAttackFlag:94,RequestAccessoryData:95,UnEquipAccessory:96,SetHighlightToSeen:97,ResetHighlights:98,UpdateAvatarAccessoryScale:99,GetThemesData:100,SetMouseSensitivity:101,StartSessionTime:102,ResetPlayerPlanetData:103,GetHighScoreList:104,SetGamePassTierOperation:105,SetGamePassTierToSeenOperation:106,SetEarningsReportToSeenOperation:107,GetTopHighScoreList:108,ClaimGamePointWelcomeReward:109,UpdateGold:110,SetActiveSpawnRole:111,CustomDevCommands:112,CreateSpawnRole:113,GetAvatarBodies:114,SetSpawnRoleBody:115,TogglePreviewTierOperation:116,ClaimRewardedAdXP:117,IncrementStatRequest:118,Undefined:119,Join:255,Leave:254,RaiseEvent:253,SetProperties:252,GetProperties:251,Ping:249};
	const MVECode = {NoCodeSet:0,UnregisterWorldObject:1,UpdateWorldObject:2,UpdateWorldObjectData:3,UpdateWorldObjectDataPartial:4,RemoveWorldObjectDataPartial:5,TransferOwnership:6,UpdateNetworkInput:7,RegisterPrototype:8,UnregisterPrototype:9,UpdatePrototype:10,UpdatePrototypeScale:11,UpdateTerrain:12,AddLink:13,RemoveLink:14,RemoveItemFromInventory:15,FriendRequest:16,FriendUpdate:17,TriggerBoxEnter:18,TriggerBoxExit:19,TriggerBoxStayBegin:20,TriggerBoxStayEnd:21,Clone:22,LockHierarchy:23,BlueprintCreationDone:24,WoUniquePrototype:25,GameStateChange:26,SyncAvatarStatus:27,ResetLogicChunk:28,UpdateWorldObjectRunTimeData:29,PickupItemStateChange:30,UpdateLineOfFire:31,WorldObjectRPCEvent:32,XPReceivedEvent:33,PostGameMsgEvent:34,SetTeam:35,AddObjectLink:36,RemoveObjectLink:37,TransferWorldObjectsToGroup:38,CloneWorldObjectTree:39,GetGameBatch:40,GameQueryReady:41,PostWinnerReport:42,CollectiblePickedUp:43,SetWorldObjectsToPurchasedEvent:44,AchievementUnlockedEvent:45,AttachWorldObjectToSeat:46,DetachWorldObjectFromVehicle:47,SpawnVehicleWithDriver:48,Reward:49,RuntimeEvent:50,ResetTerrainEvent:51,UpdateGameStat:52,UpdateGameStatType:53,UpdateAvatarMetaData:54,LevelChanged:55,GameBoostEvent:56,NotificationEvent:57,RequestMaterials:58,GetPlanetOwnershipTypes:59,GetItemCategories:60,SetupUserPlayMode:61,GameSnapshotData:62,SetActorReady:63,RequestFriends:64,GetItemInventory:65,GetItemShopInventory:66,GetBuiltInItemBusinessData:67,LargeDBQueryAvatarShopInventory:68,InitializeAvatarEdit:69,GetActiveAvatar:70,PendingByteDataBatch:71,SwitchAvatar:72,SyncronizePing:73,StartRewardCountDown:74,RewardIsReady:75,NumberOfPendingRewards:76,JoinNotification:77,CloneWorldObjectTreeWithPosition:78,CloneTempWorldObjectWithOriginalReferenceEvent:79,LogicObjectFiringStateChange:80,LogicFrame:81,CollectTheItemDropOff:82,LogicFastForward:83,LogicFastForwardEventImmediate:84,ForceDetachWorldObjectFromVehicle:85,XPReward:86,GetProfileMetaData:87,ServerError:88,SetSayChatBubbleVisible:89,GetPublishedPlanetProfileData:90,PlayerPlanetData:91,PlayerPlanetRemote:92,HighScores:93,GoldRewardedForLevel:94,NextLevelGoldReward:95,PlayerTierStateCalculatorChanged:96,GetProjectEarnings:97,TopHighScores:98,GetKogamaVat:99,GetSubscriptionPerksData:100,SetupUserAvatarEdit:101,SetupUserBuildMode:102,SetActiveSpawnRole:103,ReplicateSpawnRoleData:104,SetSpawnRoleBody:105,XPRewardedAdReady:106,Join:255,Leave:254,PropertiesChanged:253};
	const GpCode = {
		Unknown: 0,
		Null: 42,
		Dictionary: 68,
		StringArray: 97,
		Byte: 98,
		Custom: 99,
		Double: 100,
		EventData: 101,
		Float: 102,
		Hashtable: 104,
		Integer: 105,
		Short: 107,
		Long: 108,
		IntegerArray: 110,
		Boolean: 111,
		OperationResponse: 112,
		OperationRequest: 113,
		String: 115,
		ByteArray: 120,
		Array: 121,
		ObjectArray: 122
	};

	const GpType = code2type(GpCode);
	const MVEType = code2type(MVECode);
	const MVOpType = code2type(MVOpCode);
	const PhotonType = code2type(PhotonCode);





	const take = arr => new DataView(Uint8Array.from(arr).buffer);
	const put = (num, typed) => [...new Uint8Array(typed.of(num).buffer).reverse()];
	const GpValue = {
		get: {
			Unknown: arr => ({Type: GpType[arr.shift()], Value: null}),
			Null: arr => ({Type: GpType[arr.shift()], Value: null}),
			Dictionary: arr => {
				let Type = GpType[arr.shift()];
				let TKey = GpType[arr.shift()];
				let TValue = GpType[arr.shift()];
				let Size = take(arr.splice(0,2)).getInt16();
				let Value = [];

				let i = 0;
				while (i++ < Size) {
					if (!(TKey == "Unknown" || TKey == "Null")) arr.unshift(GpCode[TKey]);
					let key = GpValue.get[GpType[arr[0]]](arr);

					if (!(TValue == "Unknown" || TValue == "Null")) arr.unshift(GpCode[TValue]);
					let value = GpValue.get[GpType[arr[0]]](arr);

					Value.push([key, value]);
				}

				return {Type, TKey, TValue, Size, Value,
					get (key) {
						let slot = this.Value.find(s=>s[0].Value == key);
						if (slot) return slot[1];
						return null;
					},
					keys () {
						return this.Value.map(s=>s[0].Value);
					},
					set (key, value) {
						let slot = this.Value.find(s=>s[0].Value == key.Value);
						if (slot) slot[1] = value;
						else this.Value.push([key, value]);
					}
				};
			},
			StringArray: arr => {
				/*
								let Type = GpType[arr.shift()];
								let Size = take(arr.splice(0,2)).getInt16();
								let Value = [];

								let i = 0;
								while (i++ < Size) {
									let value = GpValue.get[arr[0]](arr);
									Value.push(value);
								}

								return {Type, Size, Value};
				*/
				console.log(GpType[arr[0]], arr.slice(0));
			},
			Byte: arr => ({Type: GpType[arr.shift()], Value: take(arr.splice(0,1)).getUint8()}),
			Custom: arr => {
				/*
								let Type = GpType[arr.shift()];
								let Size = take(arr.splice(0,2)).getInt16();
								let Value = [];

								let i = 0;
								while (i++ < Size) {
									let value = GpValue.get[arr[0]](arr);
									Value.push(value);
								}

								return {Type, Size, Value};
				*/
				console.log(GpType[arr[0]], arr.slice(0));
			},
			Double: arr => ({Type: GpType[arr.shift()], Value: take(arr.splice(0,8)).getFloat64()}),
			EventData: arr => {
				/*
								let Type = GpType[arr.shift()];
								let Size = take(arr.splice(0,2)).getInt16();
								let Value = [];

								let i = 0;
								while (i++ < Size) {
									let value = GpValue.get[arr[0]](arr);
									Value.push(value);
								}

								return {Type, Size, Value};
				*/
				console.log(GpType[arr[0]], arr.slice(0));
			},
			Float: arr => ({Type: GpType[arr.shift()], Value: take(arr.splice(0,4)).getFloat32()}),
			Hashtable: arr => {
				let Type = GpType[arr.shift()];
				let Size = take(arr.splice(0,2)).getInt16();
				let Value = [];

				let i = 0;
				while (i++ < Size) {
					let key = GpValue.get[GpType[arr[0]]](arr);
					let value = GpValue.get[GpType[arr[0]]](arr);
					Value.push([key,value]);
				}

				return {Type, Size, Value};
			},
			Integer: arr => ({Type: GpType[arr.shift()], Value: take(arr.splice(0,4)).getInt32()}),
			Short: arr => ({Type: GpType[arr.shift()], Value: take(arr.splice(0,2)).getInt16()}),
			Long: arr => ({Type: GpType[arr.shift()], Value: take(arr.splice(0,8)).getBigInt64()}),
			IntegerArray: arr => {
				/*
								let Type = GpType[arr.shift()];
								let Size = take(arr.splice(0,2)).getInt16();
								let Value = [];

								let i = 0;
								while (i++ < Size) {
									let value = GpValue.get[arr[0]](arr);
									Value.push(value);
								}

								return {Type, Size, Value};
				*/
				console.log(GpType[arr[0]], arr.slice(0));
			},
			Boolean: arr => ({Type: GpType[arr.shift()], Value: take(arr.splice(0,1)).getUint8() > 0}),
			OperationResponse: arr => {
				/*
								let Type = GpType[arr.shift()];
								let Size = take(arr.splice(0,2)).getInt16();
								let Value = [];

								let i = 0;
								while (i++ < Size) {
									let value = GpValue.get[arr[0]](arr);
									Value.push(value);
								}

								return {Type, Size, Value};
				*/
				console.log(GpType[arr[0]], arr.slice(0));
			},
			OperationRequest: arr => {
				/*
								let Type = GpType[arr.shift()];
								let Size = take(arr.splice(0,2)).getInt16();
								let Value = [];

								let i = 0;
								while (i++ < Size) {
									let value = GpValue.get[arr[0]](arr);
									Value.push(value);
								}

								return {Type, Size, Value};
				*/
				console.log(GpType[arr[0]], arr.slice(0));
			},
			String: arr => {
				let Type = GpType[arr.shift()];
				let Size = take(arr.splice(0,2)).getInt16();
				let Value = new TextDecoder().decode(Uint8Array.from(arr.splice(0, Size)));
				return {Type, Size, Value};
			},
			ByteArray: arr => {
				let Type = GpType[arr.shift()];
				let Size = take(arr.splice(0,4)).getInt32();
				let Value = Uint8Array.from(arr.splice(0, Size));
				return {Type, Size, Value};
			},
			Array: arr => {
				let Type = GpType[arr.shift()];
				let Size = take(arr.splice(0,2)).getInt16();
				let TValue = GpType[arr.shift()];
				let Value = [];

				let i = 0;
				while (i++ < Size) {
					arr.unshift(GpCode[TValue]);
					let value = GpValue.get[GpType[arr[0]]](arr);
					Value.push(value);
				}

				return {Type, Size, TValue, Value};
			},
			ObjectArray: arr => {
				/*
								let Type = GpType[arr.shift()];
								let Size = take(arr.splice(0,2)).getInt16();
								let Value = [];

								let i = 0;
								while (i++ < Size) {
									let value = GpValue.get[arr[0]](arr);
									Value.push(value);
								}

								return {Type, Size, Value};
				*/
				console.log(GpType[arr[0]], arr.slice(0));
			}
		},



		set: {
			Unknown: data => [GpCode[data.Type]],
			Null: data => [GpCode[data.Type]],
			Dictionary: data => {
				let arr = [GpCode[data.Type], GpCode[data.TKey], GpCode[data.TValue], ...put(data.Size, Int16Array)];

				for (let slot of data.Value) {
					let key = GpValue.set[slot[0].Type](slot[0]);
					if (!(data.TKey == "Unknown" || data.TKey == "Null")) key.splice(0,1);

					let value = GpValue.set[slot[1].Type](slot[1]);
					if (!(data.TValue == "Unknown" || data.TValue == "Null")) value.splice(0,1);

					arr.push(...key, ...value);
				}

				return arr;
			},
			StringArray: data => [GpCode[data.Type]],
			Byte: data => [GpCode[data.Type], ...put(data.Value, Uint8Array)],
			Custom: data => [GpCode[data.Type]],
			Double: data => [GpCode[data.Type], ...put(data.Value, Float64Array)],
			EventData: data => [GpCode[data.Type]],
			Float: data => [GpCode[data.Type], ...put(data.Value, Float32Array)],
			Hashtable: data => {
				let arr = [GpCode[data.Type], ...put(data.Size, Int16Array)];

				for (let slot of data.Value) {
					let key = GpValue.set[slot[0].Type](slot[0]);
					let value = GpValue.set[slot[1].Type](slot[1]);
					arr.push(...key,...value);
				}

				return arr;
			},
			Integer: data => [GpCode[data.Type], ...put(data.Value, Int32Array)],
			Short: data => [GpCode[data.Type], ...put(data.Value, Int16Array)],
			Long: data => [GpCode[data.Type], ...put(data.Value, BigInt64Array)],
			IntegerArray: data => [GpCode[data.Type]],
			Boolean: data => [GpCode[data.Type], ...put(data.Value > 0, Uint8Array)],
			OperationResponse: data => [GpCode[data.Type]],
			OperationRequest: data => [GpCode[data.Type]],
			String: data => [GpCode[data.Type], ...put(data.Size, Int16Array), ...new TextEncoder().encode(data.Value)],
			ByteArray: data => [GpCode[data.Type], ...put(data.Size, Int32Array), ...data.Value],
			Array: data => {
				let arr = [GpCode[data.Type], ...put(data.Size, Int16Array), GpCode[data.TValue]];

				for (let value of data.Value) {
					arr.push(...GpValue.set[value.Type](value).slice(1));
				}

				return arr;
			},
			ObjectArray: data => [GpCode[data.Type]]
		}
	};





	const typeOf = packet => {
		const MagicNumber = packet[0];
		if (MagicNumber == 0xF0) return "Ping";
		
		const flag = packet[1]&127;
		const code = packet[2];
		if (flag == 7 && code == PhotonCode.Ping) return "Ping";

		return {
			1: "Connected",
			2: MVOpType[code],
			3: MVOpType[code],
			4: MVEType[code],
			6: "Ping",
			7: MVOpType[code],
			8: "UnknownMessage",
			9: "Unknown"
		}[flag] || "Unknown";
	};





	const getParams = packet => {
		const data = {};

		const size = take(packet.splice(0,2)).getInt16();
		let i = 0;

		while (i < size) {
			data[packet.shift()] = GpValue.get[GpType[packet[0]]](packet);
			i++;
		}

		return data;
	};
	const decode = packet => {
		const type = typeOf(packet);
		if (type == "Ping" || type == "Unknown" || type == "Connected") return null;

		const flag = packet[1]&127;
		if (flag != 1 && (packet[1]&128) > 0) return null; //need decrypt message

		const data = {};
		data.magicNumber = packet.shift();
		data.flag = packet.shift();
		if (flag == 8) {
			data.message = GpValue.get[GpType[packet[0]]](packet);
			return data;
		}

		data.opCode = (flag == 4 ? MVEType : MVOpType)[packet.shift()];
		if (flag == 3 || flag == 7) {
			data.returnCode = take(packet.splice(0,2)).getInt16();
			data.debugMessage = GpValue.get[GpType[packet[0]]](packet);
		}
		data.params = getParams(packet);

		return data;
	};





	const setParams = data => {
		const packet = [];

		packet.push(...put(Object.keys(data.params).length, Int16Array));

		for (const slot in data.params) {
			const value = data.params[slot];
			packet.push(+slot, ...GpValue.set[value.Type](value));
		}

		return packet;
	};
	const encode = data => {
		if (typeof data == null) return null;
		if (typeof data !== 'object') return [...data];

		const packet = [];
		packet.push(data.magicNumber, data.flag);

		const flag = data.flag&127;
		if (flag == 8) {
			packet.push(...GpValue.set[data.message.Type](data.message));
			return packet;
		}

		packet.push((flag == 4 ? MVECode : MVOpCode)[data.opCode]);
		if (flag == 3 || flag == 7) {
			packet.push(...put(data.returnCode, Int16Array));
			packet.push(...GpValue.set[data.debugMessage.Type](data.debugMessage));
		}
		packet.push(...setParams(data));

		return packet;
	};





	return {
		typeOf,
		decode,
		encode
	};
})();
// 0vC4#7152