Greasy Fork is available in English.

KPD

Kogama Packet Decoder

Ce script ne doit pas être installé directement. C'est une librairie destinée à être incluse dans d'autres scripts avec la méta-directive // @require https://update.greasyfork.org/scripts/441869/1034053/KPD.js

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==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