mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
feat: start of proto only
This commit is contained in:
1 parent
d90a3cc010
commit
45dc99e1ce
19 files changed
+365
-891
No files matched your search
@@ -1,99 +0,0 @@
|
|||||||
# Cedilla Object Notation
|
|
||||||
|
|
||||||
1. JSON compressed as CDON, written directly to disk (a direct 50% reduction).
|
|
||||||
2. CDON further compressed with LZ4 (a clean 90% reduction).
|
|
||||||
3. The raw JSON file as fetched from a random data source.
|
|
||||||
4. CDON decompressed once again to JSON. Note that this file is a little larger than the original JSON file as it contains a lot more decimal places due to float precision (this shouldn't affect the size in memory).
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
FS stands for "Fast String".
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
primary CedillaObjectNotation {
|
|
||||||
utf8"CDON" magic;
|
|
||||||
Header header;
|
|
||||||
primary Body<header.fsFormat> body;
|
|
||||||
}
|
|
||||||
|
|
||||||
Header {
|
|
||||||
uint16 version; // always 1
|
|
||||||
FSFormat fsFormat;
|
|
||||||
StringTable<fsFormat> stringTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
FSFormat enum<uint8> {
|
|
||||||
Format8,
|
|
||||||
Format16,
|
|
||||||
Format32,
|
|
||||||
}
|
|
||||||
|
|
||||||
FSPrimitive<FSFormat fsFormat> match(fsFormat) {
|
|
||||||
Format8: uint8;
|
|
||||||
Format16: uint16;
|
|
||||||
Format32: uint32;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringTable<FSFormat fsFormat> {
|
|
||||||
FSPrimitive<fsFormat> count;
|
|
||||||
String[count] strings;
|
|
||||||
}
|
|
||||||
|
|
||||||
Body<FSFormat fsFormat> {
|
|
||||||
primary Value<fsFormat> object;
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueType enum<uint8> {
|
|
||||||
Null,
|
|
||||||
Boolean,
|
|
||||||
Uint8,
|
|
||||||
Uint16,
|
|
||||||
Uint32,
|
|
||||||
Uint64,
|
|
||||||
Int8,
|
|
||||||
Int16,
|
|
||||||
Int32,
|
|
||||||
Int64,
|
|
||||||
Float32,
|
|
||||||
Float64,
|
|
||||||
String,
|
|
||||||
FS,
|
|
||||||
Array,
|
|
||||||
Object,
|
|
||||||
}
|
|
||||||
|
|
||||||
String {
|
|
||||||
uint32 length;
|
|
||||||
primary utf8<length> value;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringValue Value & { (ValueType.String | ValueType.FS) type }
|
|
||||||
|
|
||||||
Value<FSFormat fsFormat> {
|
|
||||||
ValueType type;
|
|
||||||
match<type> {
|
|
||||||
Boolean: { uint8 value; }
|
|
||||||
Uint8: { uint8 value; }
|
|
||||||
Uint16: { uint16 value; }
|
|
||||||
Uint32: { uint32 value; }
|
|
||||||
Uint64: { uint64 value; }
|
|
||||||
Int8: { int8 value; }
|
|
||||||
Int16: { int16 value; }
|
|
||||||
Int32: { int32 value; }
|
|
||||||
Int64: { int64 value; }
|
|
||||||
Float32: { float32 value; }
|
|
||||||
Float64: { float64 value; }
|
|
||||||
String: { String value; }
|
|
||||||
FS: { FSPrimitive<fsFormat> index; }
|
|
||||||
Array: {
|
|
||||||
uint32 count;
|
|
||||||
Value[count] values;
|
|
||||||
}
|
|
||||||
Object: {
|
|
||||||
uint32 count;
|
|
||||||
StringValue[count] keys;
|
|
||||||
Value[count] values;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
+4
-2
@@ -28,19 +28,21 @@
|
|||||||
"format": "prettier --write \"**/*.@(json|js|jsx|css|md|ts|tsx|html|xml|yml|gltf)\"",
|
"format": "prettier --write \"**/*.@(json|js|jsx|css|md|ts|tsx|html|xml|yml|gltf)\"",
|
||||||
"update": "yarn upgrade --latest",
|
"update": "yarn upgrade --latest",
|
||||||
"tunnel": "cloudflared tunnel --url http://localhost:3000",
|
"tunnel": "cloudflared tunnel --url http://localhost:3000",
|
||||||
"discoverids": "scripts/discoverIds.ts"
|
"discoverids": "scripts/discoverIds.ts",
|
||||||
|
"build:protos": "bun packages/scripts/src/protos.ts"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lodash-es": "^4.17.21"
|
"lodash-es": "^4.17.21"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash-es": "^4.17.12",
|
|
||||||
"@types/bun": "latest",
|
"@types/bun": "latest",
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.5.4",
|
"@types/node": "^22.5.4",
|
||||||
"esbuild": "^0.19.12",
|
"esbuild": "^0.19.12",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"prisma": "^5.19.1",
|
"prisma": "^5.19.1",
|
||||||
|
"ts-protoc-gen": "^0.15.0",
|
||||||
"typescript": "^5.5.4"
|
"typescript": "^5.5.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,298 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package BattleResultsGenerated;
|
|
||||||
|
|
||||||
import "PlayerAvatarImage.proto";
|
|
||||||
|
|
||||||
message Int32List {
|
|
||||||
repeated int32 values = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message PlayerInfo {
|
|
||||||
message AvatarEntry {
|
|
||||||
int32 key = 1;
|
|
||||||
.PlayerAvatarInfo value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
string name = 1;
|
|
||||||
int32 prebattleID = 2;
|
|
||||||
int32 team = 3;
|
|
||||||
int64 clanID = 4;
|
|
||||||
string clanTag = 5;
|
|
||||||
repeated int32 chatMessageCount = 6;
|
|
||||||
repeated .BattleResultsGenerated.PlayerInfo.AvatarEntry avatar = 7;
|
|
||||||
int32 profileBackground = 8;
|
|
||||||
int32 vehicleRank = 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TeamInfo {
|
|
||||||
string title = 1;
|
|
||||||
string icon = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message VehiclePublicResults {
|
|
||||||
message ExtVehAchievementsEntry {
|
|
||||||
int32 key = 1;
|
|
||||||
int32 value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ExtAccAchievementsEntry {
|
|
||||||
int32 key = 1;
|
|
||||||
int32 value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 health = 1;
|
|
||||||
int32 credits = 2;
|
|
||||||
int32 xp = 3;
|
|
||||||
int32 shots = 4;
|
|
||||||
int32 directHits = 5;
|
|
||||||
int32 explosionHits = 6;
|
|
||||||
int32 piercings = 7;
|
|
||||||
int32 damageDealt = 8;
|
|
||||||
int32 damageAssistedRadio = 9;
|
|
||||||
int32 damageAssistedTrack = 10;
|
|
||||||
int32 damageReceived = 11;
|
|
||||||
int32 directHitsReceived = 12;
|
|
||||||
int32 noDamageDirectHitsReceived = 13;
|
|
||||||
int32 explosionHitsReceived = 14;
|
|
||||||
int32 piercingsReceived = 15;
|
|
||||||
int32 spotted = 16;
|
|
||||||
int32 damaged = 17;
|
|
||||||
int32 kills = 18;
|
|
||||||
int32 tdamageDealt = 19;
|
|
||||||
int32 tkills = 20;
|
|
||||||
int32 capturePoints = 21;
|
|
||||||
int32 droppedCapturePoints = 22;
|
|
||||||
int32 mileage = 23;
|
|
||||||
int32 lifeTime = 24;
|
|
||||||
int32 killerID = 25;
|
|
||||||
repeated int32 achievements = 26;
|
|
||||||
repeated .BattleResultsGenerated.VehiclePublicResults.ExtVehAchievementsEntry extVehAchievements = 27;
|
|
||||||
repeated .BattleResultsGenerated.VehiclePublicResults.ExtAccAchievementsEntry extAccAchievements = 28;
|
|
||||||
int32 xpDamage = 29;
|
|
||||||
int32 xpAssist = 30;
|
|
||||||
int32 xpTeamBonus = 31;
|
|
||||||
int32 wpEarned = 32;
|
|
||||||
int32 wpStolen = 33;
|
|
||||||
int32 heroCreditsBonus = 34;
|
|
||||||
int32 heroXpBonus = 35;
|
|
||||||
int64 accountDBID = 101;
|
|
||||||
int32 team = 102;
|
|
||||||
int32 serializedVehType = 103;
|
|
||||||
int32 gold = 104;
|
|
||||||
int32 deathReason = 105;
|
|
||||||
int32 camouflage = 106;
|
|
||||||
float mmr = 107;
|
|
||||||
float mmrDiff = 108;
|
|
||||||
int32 calibrationBattlesLeft = 109;
|
|
||||||
int32 healedHP = 114;
|
|
||||||
int32 wasHealedFor = 115;
|
|
||||||
int32 xpActivity = 36;
|
|
||||||
int32 customization = 116;
|
|
||||||
int32 potentialEnemyDamage = 117;
|
|
||||||
int32 rammingDamage = 118;
|
|
||||||
int32 helpedToKill = 119;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BattleResultsFinalXp {
|
|
||||||
int32 xpDamagePure = 1;
|
|
||||||
int32 xpDamagePrem = 2;
|
|
||||||
int32 xpAssistPure = 3;
|
|
||||||
int32 xpAssistPrem = 4;
|
|
||||||
int32 xpActivityPure = 5;
|
|
||||||
int32 xpActivityPrem = 6;
|
|
||||||
int32 xpTeamBonusPure = 7;
|
|
||||||
int32 xpTeamBonusPrem = 8;
|
|
||||||
int32 healingXpPure = 9;
|
|
||||||
int32 healingXpPrem = 10;
|
|
||||||
int32 heroXpBonusPure = 11;
|
|
||||||
int32 heroXpBonusPrem = 12;
|
|
||||||
int32 earnedFreeXpPure = 13;
|
|
||||||
int32 earnedFreeXpPrem = 14;
|
|
||||||
int32 earnedAvatarXpPure = 15;
|
|
||||||
int32 earnedAvatarXpPrem = 16;
|
|
||||||
int32 xpNoModifiers = 17;
|
|
||||||
int32 xpPure = 18;
|
|
||||||
int32 xpPrem = 19;
|
|
||||||
int32 totalFreeXpPure = 20;
|
|
||||||
int32 totalFreeXpPrem = 21;
|
|
||||||
int32 totalAvatarXpPure = 22;
|
|
||||||
int32 totalAvatarXpPrem = 23;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Ribbons {
|
|
||||||
int32 id = 1;
|
|
||||||
int32 grade = 2;
|
|
||||||
int32 amount = 3;
|
|
||||||
int32 value = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BattleResultsUpdate {
|
|
||||||
message ExcellentBattleDataEntry {
|
|
||||||
string key = 1;
|
|
||||||
int32 value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message StuffEntry {
|
|
||||||
int32 key = 1;
|
|
||||||
int32 value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RatingBattleStuffBonusEntry {
|
|
||||||
int32 key = 1;
|
|
||||||
int32 value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 avatarXP = 1;
|
|
||||||
int32 eventCredits = 2;
|
|
||||||
int32 eventGold = 3;
|
|
||||||
int32 eventXP = 4;
|
|
||||||
int32 eventFreeXP = 5;
|
|
||||||
int32 eventAvatarXP = 6;
|
|
||||||
int32 autoRepairCost = 7;
|
|
||||||
repeated int32 autoLoadCost = 8;
|
|
||||||
repeated int32 autoEquipCost = 9;
|
|
||||||
repeated int32 autoProvCost = 10;
|
|
||||||
bool isPremium = 12;
|
|
||||||
int32 premiumXPFactor10 = 13;
|
|
||||||
int32 premiumCreditsFactor10 = 14;
|
|
||||||
int32 xpFactor10 = 15;
|
|
||||||
int32 creditsFactor10 = 16;
|
|
||||||
int32 aogasFactor10 = 17;
|
|
||||||
int32 markOfMastery = 18;
|
|
||||||
repeated .BattleResultsGenerated.BattleResultsUpdate.ExcellentBattleDataEntry excellentBattleData = 19;
|
|
||||||
bytes vehDossier = 20;
|
|
||||||
bytes accDossier = 21;
|
|
||||||
bytes vehDossierPrev = 22;
|
|
||||||
bytes accDossierPrev = 23;
|
|
||||||
int32 autoRepairDiscount = 24;
|
|
||||||
repeated int32 autoEquipDiscount = 25;
|
|
||||||
repeated int32 autoProvDiscount = 26;
|
|
||||||
repeated .BattleResultsGenerated.BattleResultsUpdate.StuffEntry stuff = 27;
|
|
||||||
int32 boosterCredits = 29;
|
|
||||||
int32 boosterXp = 30;
|
|
||||||
int32 boosterFreeXp = 31;
|
|
||||||
int32 boosterAvatarXp = 32;
|
|
||||||
int32 complimentsLimit = 33;
|
|
||||||
repeated int32 autoAbilsCost = 34;
|
|
||||||
repeated int32 autoAbilsDiscount = 35;
|
|
||||||
bool hasHealingReward = 36;
|
|
||||||
int32 healingCredits = 37;
|
|
||||||
int32 healingXp = 38;
|
|
||||||
int32 healingFreeXp = 39;
|
|
||||||
int32 healingAvatarXp = 40;
|
|
||||||
float mmr = 107;
|
|
||||||
float mmrDiff = 108;
|
|
||||||
int32 calibrationBattlesLeft = 109;
|
|
||||||
int32 ratingBattleXp = 110;
|
|
||||||
int32 ratingBattleFreeXp = 111;
|
|
||||||
int32 ratingBattleAvatarXp = 112;
|
|
||||||
repeated .BattleResultsGenerated.BattleResultsUpdate.RatingBattleStuffBonusEntry ratingBattleStuffBonus = 113;
|
|
||||||
repeated .BattleResultsGenerated.Ribbons ribbons = 114;
|
|
||||||
}
|
|
||||||
|
|
||||||
message DropData {
|
|
||||||
message StuffEntry {
|
|
||||||
int32 key = 1;
|
|
||||||
int32 value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 credits = 1;
|
|
||||||
int32 gold = 2;
|
|
||||||
int32 xp = 3;
|
|
||||||
int32 freeXP = 4;
|
|
||||||
int32 avatarXP = 5;
|
|
||||||
repeated .BattleResultsGenerated.DropData.StuffEntry stuff = 27;
|
|
||||||
}
|
|
||||||
|
|
||||||
message VehicleInteractionDetails {
|
|
||||||
message DamagedModulesEntry {
|
|
||||||
int32 key = 1;
|
|
||||||
int32 value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message DestroyedModulesEntry {
|
|
||||||
int32 key = 1;
|
|
||||||
int32 value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool spotted = 1;
|
|
||||||
int32 deathReason = 2;
|
|
||||||
int32 directHits = 3;
|
|
||||||
int32 directHitWithoutDamage = 4;
|
|
||||||
int32 explosionHits = 5;
|
|
||||||
int32 piercings = 6;
|
|
||||||
int32 damageDealt = 7;
|
|
||||||
int32 damageAssistedTrack = 8;
|
|
||||||
int32 damageAssistedRadio = 9;
|
|
||||||
int32 fire = 10;
|
|
||||||
repeated .BattleResultsGenerated.VehicleInteractionDetails.DamagedModulesEntry damagedModules = 11;
|
|
||||||
repeated .BattleResultsGenerated.VehicleInteractionDetails.DestroyedModulesEntry destroyedModules = 12;
|
|
||||||
int32 ricochetHitWithoutDamage = 13;
|
|
||||||
}
|
|
||||||
|
|
||||||
message InteractionDetails {
|
|
||||||
message VehiclesEntry {
|
|
||||||
int32 key = 1;
|
|
||||||
.BattleResultsGenerated.VehicleInteractionDetails value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
repeated .BattleResultsGenerated.InteractionDetails.VehiclesEntry vehicles = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message PrebattleStats {
|
|
||||||
int32 freeXp = 1;
|
|
||||||
int32 vehicleXp = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BattleResultsClient {
|
|
||||||
message QuestsProgressEntry {
|
|
||||||
string key = 1;
|
|
||||||
.BattleResultsGenerated.Int32List value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message DropCategoriesEntry {
|
|
||||||
string key = 1;
|
|
||||||
.BattleResultsGenerated.DropData value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message PlayersEntry {
|
|
||||||
int64 key = 1;
|
|
||||||
.BattleResultsGenerated.PlayerInfo value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message VehiclesEntry {
|
|
||||||
int32 key = 1;
|
|
||||||
.BattleResultsGenerated.VehiclePublicResults value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 arenaTypeID = 1;
|
|
||||||
int32 arenaCreateTime = 2;
|
|
||||||
int32 winnerTeam = 3;
|
|
||||||
int32 finishReason = 4;
|
|
||||||
int32 duration = 5;
|
|
||||||
int32 bonusType = 6;
|
|
||||||
int32 vehLockMode = 7;
|
|
||||||
.BattleResultsGenerated.VehiclePublicResults public = 8;
|
|
||||||
int32 gameModeID = 9;
|
|
||||||
int32 observerMode = 10;
|
|
||||||
.BattleResultsGenerated.BattleResultsFinalXp finalXp = 11;
|
|
||||||
int32 repair = 136;
|
|
||||||
int32 freeXP = 137;
|
|
||||||
int32 xpPenalty = 145;
|
|
||||||
int32 creditsPenalty = 146;
|
|
||||||
int32 creditsContributionIn = 147;
|
|
||||||
int32 creditsContributionOut = 148;
|
|
||||||
.BattleResultsGenerated.BattleResultsUpdate update = 150;
|
|
||||||
int32 originalXP = 181;
|
|
||||||
int32 originalFreeXP = 182;
|
|
||||||
int32 originalCredits = 183;
|
|
||||||
repeated .BattleResultsGenerated.BattleResultsClient.QuestsProgressEntry questsProgress = 184;
|
|
||||||
repeated .BattleResultsGenerated.BattleResultsClient.DropCategoriesEntry dropCategories = 185;
|
|
||||||
.BattleResultsGenerated.TeamInfo teamInfo = 186;
|
|
||||||
repeated .BattleResultsGenerated.BattleResultsClient.PlayersEntry players = 201;
|
|
||||||
repeated .BattleResultsGenerated.BattleResultsClient.VehiclesEntry vehicles = 301;
|
|
||||||
.BattleResultsGenerated.InteractionDetails interactionDetails = 302;
|
|
||||||
.BattleResultsGenerated.PrebattleStats prebattleStats = 303;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
message PlayerAvatarInfo {
|
|
||||||
uint32 id = 1;
|
|
||||||
string image = 2;
|
|
||||||
string image_retina = 3;
|
|
||||||
string grade = 4;
|
|
||||||
}
|
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,223 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package blitzkit;
|
||||||
|
|
||||||
|
message TankDefinitions {
|
||||||
|
map<uint32, TankDefinition> tanks = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TankDefinition {
|
||||||
|
uint32 id = 1;
|
||||||
|
map<uint32, uint32> roles = 2;
|
||||||
|
optional string description = 3;
|
||||||
|
bool fixed_camouflage = 4;
|
||||||
|
repeated int32 camouflages = 5;
|
||||||
|
repeated int32 ancestors = 6;
|
||||||
|
repeated int32 successors = 7;
|
||||||
|
repeated Crew crew = 8;
|
||||||
|
uint32 health = 9;
|
||||||
|
string nation = 10;
|
||||||
|
string name = 11;
|
||||||
|
optional string name_full = 12;
|
||||||
|
TankType type = 13;
|
||||||
|
uint32 max_consumables = 14;
|
||||||
|
uint32 max_provisions = 15;
|
||||||
|
Tier tier = 16;
|
||||||
|
TankClass class = 17;
|
||||||
|
bool testing = 18;
|
||||||
|
bool deprecated = 19;
|
||||||
|
repeated TurretDefinition turrets = 20;
|
||||||
|
repeated EngineDefinition engines = 21;
|
||||||
|
repeated TrackDefinition tracks = 22;
|
||||||
|
TankPrice price = 23;
|
||||||
|
optional uint32 xp = 24;
|
||||||
|
float speed_forwards = 25;
|
||||||
|
float speed_backwards = 26;
|
||||||
|
float camouflage_still = 27;
|
||||||
|
float camouflage_moving = 28;
|
||||||
|
float camouflage_onFire = 29;
|
||||||
|
string equipment_preset = 30;
|
||||||
|
uint32 weight = 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TankPriceType {
|
||||||
|
TYPE_UNSPECIFIED = 0;
|
||||||
|
TYPE_CREDITS = 1;
|
||||||
|
TYPE_GOLD = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TankPrice {
|
||||||
|
TankPriceType type = 1;
|
||||||
|
uint32 value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TrackDefinition {
|
||||||
|
uint32 id = 1;
|
||||||
|
Tier tier = 2;
|
||||||
|
string name = 3;
|
||||||
|
uint32 weight = 4;
|
||||||
|
float traverse_speed = 5;
|
||||||
|
optional uint32 xp = 6;
|
||||||
|
float dispersion_move = 7;
|
||||||
|
float dispersion_traverse = 8;
|
||||||
|
float resistance_hard = 9;
|
||||||
|
float resistance_medium = 10;
|
||||||
|
float resistance_soft = 11;
|
||||||
|
repeated Unlock unlocks = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
message EngineDefinition {
|
||||||
|
uint32 id = 1;
|
||||||
|
string name = 2;
|
||||||
|
optional uint32 xp = 3;
|
||||||
|
Tier tier = 4;
|
||||||
|
optional float fire_chance = 5;
|
||||||
|
uint32 power = 6;
|
||||||
|
uint32 weight = 7;
|
||||||
|
repeated Unlock unlocks = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TurretDefinition {
|
||||||
|
uint32 id = 1;
|
||||||
|
uint32 health = 2;
|
||||||
|
uint32 view_range = 3;
|
||||||
|
float traverse_speed = 4;
|
||||||
|
optional uint32 xp = 5;
|
||||||
|
string name = 6;
|
||||||
|
uint32 tier = 7;
|
||||||
|
uint32 weight = 8;
|
||||||
|
repeated GunDefinition guns = 9;
|
||||||
|
repeated Unlock unlocks = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GunDefinition {
|
||||||
|
oneof gun_type {
|
||||||
|
GunDefinitionRegular regular = 1;
|
||||||
|
GunDefinitionAutoLoader auto_loader = 2;
|
||||||
|
GunDefinitionAutoReloader auto_reloader = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message GunDefinitionRegular {
|
||||||
|
GunDefinitionBase gun = 1;
|
||||||
|
GunDefinitionRegularProperties regular = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GunDefinitionAutoLoader {
|
||||||
|
GunDefinitionBase gun = 1;
|
||||||
|
GunDefinitionAutoLoaderProperties auto_loader = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GunDefinitionAutoReloader {
|
||||||
|
GunDefinitionBase gun = 1;
|
||||||
|
GunDefinitionAutoReloaderProperties auto_reloader = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GunDefinitionBase {
|
||||||
|
uint32 id = 1;
|
||||||
|
float rotation_speed = 2;
|
||||||
|
optional uint32 xp = 3;
|
||||||
|
uint32 weight = 4;
|
||||||
|
string name = 5;
|
||||||
|
uint32 tier = 6;
|
||||||
|
repeated ShellDefinition shells = 7;
|
||||||
|
float camouflage_loss = 8;
|
||||||
|
float aim_time = 9;
|
||||||
|
float dispersion_base = 10;
|
||||||
|
float dispersion_traverse = 11;
|
||||||
|
float dispersion_shot = 12;
|
||||||
|
float dispersion_damaged = 13;
|
||||||
|
repeated Unlock unlocks = 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShellDefinition {
|
||||||
|
uint32 id = 1;
|
||||||
|
string name = 2;
|
||||||
|
uint32 velocity = 3;
|
||||||
|
uint32 armor_damage = 4;
|
||||||
|
uint32 module_damage = 5;
|
||||||
|
uint32 caliber = 6;
|
||||||
|
string icon = 7;
|
||||||
|
ShellPenetration penetration = 8;
|
||||||
|
ShellType type = 9;
|
||||||
|
uint32 normalization = 10;
|
||||||
|
uint32 ricochet = 11;
|
||||||
|
uint32 explosion_radius = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ShellType {
|
||||||
|
SHELL_UNSPECIFIED = 0;
|
||||||
|
SHELL_AP = 1;
|
||||||
|
SHELL_APCR = 2;
|
||||||
|
SHELL_HEAT = 3;
|
||||||
|
SHELL_HE = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShellPenetration {
|
||||||
|
uint32 near = 1;
|
||||||
|
uint32 far = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Unlock {
|
||||||
|
int32 id = 1;
|
||||||
|
ModuleType type = 2;
|
||||||
|
UnlockCost cost = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UnlockCost {
|
||||||
|
string type = 1;
|
||||||
|
int32 value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ModuleType {
|
||||||
|
MODULE_UNSPECIFIED = 0;
|
||||||
|
MODULE_VEHICLE = 1;
|
||||||
|
MODULE_ENGINE = 2;
|
||||||
|
MODULE_TRACKS = 3;
|
||||||
|
MODULE_TURRET = 4;
|
||||||
|
MODULE_GUN = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TankClass {
|
||||||
|
CLASS_UNSPECIFIED = 0;
|
||||||
|
CLASS_LIGHT = 1;
|
||||||
|
CLASS_MEDIUM = 2;
|
||||||
|
CLASS_HEAVY = 3;
|
||||||
|
CLASS_TANK_DESTROYER = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Tier {
|
||||||
|
TIER_UNSPECIFIED = 0;
|
||||||
|
TIER_I = 1;
|
||||||
|
TIER_II = 2;
|
||||||
|
TIER_III = 3;
|
||||||
|
TIER_IV = 4;
|
||||||
|
TIER_V = 5;
|
||||||
|
TIER_VI = 6;
|
||||||
|
TIER_VII = 7;
|
||||||
|
TIER_VIII = 8;
|
||||||
|
TIER_IX = 9;
|
||||||
|
TIER_X = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TankType {
|
||||||
|
TYPE_UNSPECIFIED = 0;
|
||||||
|
TYPE_RESEARCHABLE = 1;
|
||||||
|
TYPE_PREMIUM = 2;
|
||||||
|
TYPE_COLLECTOR = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Crew {
|
||||||
|
CrewType type = 1;
|
||||||
|
uint32 count = 2;
|
||||||
|
repeated CrewType substitute = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CrewType {
|
||||||
|
CREW_UNSPECIFIED = 0;
|
||||||
|
CREW_COMMANDER = 1;
|
||||||
|
CREW_RADIOMAN = 2;
|
||||||
|
CREW_GUNNER = 3;
|
||||||
|
CREW_DRIVER = 4;
|
||||||
|
CREW_LOADER = 5;
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import { superDecompress } from './superDecompress';
|
|
||||||
|
|
||||||
export async function fetchCdonLz4<Type>(url: string) {
|
|
||||||
return await fetch(url, { cache: 'no-store' })
|
|
||||||
.then((response) => response.arrayBuffer())
|
|
||||||
.then((buffer) => superDecompress<Type>(buffer));
|
|
||||||
}
|
|
||||||
@@ -13,7 +13,6 @@ export * from './degressiveStat';
|
|||||||
// export * from './emblemURL';
|
// export * from './emblemURL';
|
||||||
export * from './equipmentDefinitions';
|
export * from './equipmentDefinitions';
|
||||||
export * from './eventManager';
|
export * from './eventManager';
|
||||||
// export * from './fetchCdonLz4';
|
|
||||||
// export * from './flagUserActivity';
|
// export * from './flagUserActivity';
|
||||||
export * from './gameDefinitions';
|
export * from './gameDefinitions';
|
||||||
// export * from './getArchivedLatestSeasonNumber';
|
// export * from './getArchivedLatestSeasonNumber';
|
||||||
@@ -36,8 +35,6 @@ export * from './resolvePenetrationCoefficient';
|
|||||||
export * from './reviews';
|
export * from './reviews';
|
||||||
export * from './skillDefinitions';
|
export * from './skillDefinitions';
|
||||||
export * from './sum';
|
export * from './sum';
|
||||||
export * from './superCompress';
|
|
||||||
export * from './superDecompress';
|
|
||||||
export * from './tankDefinitions';
|
export * from './tankDefinitions';
|
||||||
export * from './tankIcon';
|
export * from './tankIcon';
|
||||||
export * from './tankNames';
|
export * from './tankNames';
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
import { compress } from 'lz4js';
|
|
||||||
import { CdonWriteStream } from '../streams';
|
|
||||||
|
|
||||||
export function superCompress(object: any) {
|
|
||||||
const write = new CdonWriteStream().cdon(object);
|
|
||||||
const compressed = compress(write.uint8Array);
|
|
||||||
return Buffer.from(compressed).toString('base64');
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import { decompress } from 'lz4js';
|
|
||||||
import { CdonReadStream } from '../streams';
|
|
||||||
|
|
||||||
export function superDecompress<Type>(buffer: ArrayBuffer) {
|
|
||||||
const decompressed = decompress(new Uint8Array(buffer)).buffer as ArrayBuffer;
|
|
||||||
const read = new CdonReadStream(decompressed);
|
|
||||||
return read.cdon() as Type;
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
CrewMember,
|
CrewType,
|
||||||
GunDefinition,
|
GunDefinition,
|
||||||
ShellType,
|
ShellType,
|
||||||
TankClass,
|
TankClass,
|
||||||
|
TankType,
|
||||||
Tier,
|
Tier,
|
||||||
TreeType,
|
|
||||||
} from '.';
|
} from '.';
|
||||||
|
|
||||||
export const SHELL_NAMES: Record<ShellType, string> = {
|
export const SHELL_NAMES: Record<ShellType, string> = {
|
||||||
@@ -13,7 +13,7 @@ export const SHELL_NAMES: Record<ShellType, string> = {
|
|||||||
hc: 'HEAT',
|
hc: 'HEAT',
|
||||||
he: 'HE',
|
he: 'HE',
|
||||||
};
|
};
|
||||||
export const CREW_MEMBER_NAMES: Record<CrewMember, string> = {
|
export const CREW_MEMBER_NAMES: Record<CrewType, string> = {
|
||||||
commander: 'Commander',
|
commander: 'Commander',
|
||||||
radioman: 'Radioman',
|
radioman: 'Radioman',
|
||||||
gunner: 'Gunner',
|
gunner: 'Gunner',
|
||||||
@@ -77,7 +77,7 @@ export const flags: Record<string, string> = {
|
|||||||
european: '🇪🇺',
|
european: '🇪🇺',
|
||||||
other: '<:other:1218421572243558482>',
|
other: '<:other:1218421572243558482>',
|
||||||
};
|
};
|
||||||
export const TREE_TYPE_ICONS: Record<TreeType, Record<TankClass, string>> = {
|
export const TREE_TYPE_ICONS: Record<TankType, Record<TankClass, string>> = {
|
||||||
researchable: TANK_ICONS,
|
researchable: TANK_ICONS,
|
||||||
premium: TANK_ICONS_PREMIUM,
|
premium: TANK_ICONS_PREMIUM,
|
||||||
collector: TANK_ICONS_COLLECTOR,
|
collector: TANK_ICONS_COLLECTOR,
|
||||||
|
|||||||
@@ -1,27 +1,48 @@
|
|||||||
import { Vector2Tuple } from 'three';
|
import { Vector2Tuple } from 'three';
|
||||||
import { TANK_CLASSES, TREE_TYPES } from '../../blitz/constants';
|
|
||||||
import { asset } from '../asset';
|
import { asset } from '../asset';
|
||||||
import { fetchCdonLz4 } from '../fetchCdonLz4';
|
import { fetchCdonLz4 } from '../fetchCdonLz4';
|
||||||
import { TIERS } from './constants';
|
|
||||||
|
|
||||||
export type TankClass = (typeof TANK_CLASSES)[number];
|
export enum TankClass {
|
||||||
export type TreeType = (typeof TREE_TYPES)[number];
|
Unspecified,
|
||||||
|
Light,
|
||||||
|
Medium,
|
||||||
|
Heavy,
|
||||||
|
TankDestroyer,
|
||||||
|
}
|
||||||
|
export enum TankType {
|
||||||
|
Unspecified,
|
||||||
|
Researchable,
|
||||||
|
Premium,
|
||||||
|
Collector,
|
||||||
|
}
|
||||||
|
|
||||||
export enum ShellType {
|
export enum ShellType {
|
||||||
AP = 'ap',
|
Unspecified,
|
||||||
APCR = 'ap_cr',
|
AP,
|
||||||
HEAT = 'hc',
|
APCR,
|
||||||
HE = 'he',
|
HEAT,
|
||||||
|
HE,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum CrewType {
|
||||||
|
Unspecified,
|
||||||
|
Commander,
|
||||||
|
Radioman,
|
||||||
|
Gunner,
|
||||||
|
Driver,
|
||||||
|
Loader,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CrewMember =
|
|
||||||
| 'commander'
|
|
||||||
| 'radioman'
|
|
||||||
| 'gunner'
|
|
||||||
| 'driver'
|
|
||||||
| 'loader';
|
|
||||||
export type TankDefinitions = Record<number, TankDefinition>;
|
export type TankDefinitions = Record<number, TankDefinition>;
|
||||||
export type ModuleType = 'vehicle' | 'engine' | 'chassis' | 'turret' | 'gun';
|
export enum ModuleType {
|
||||||
|
Unspecified,
|
||||||
|
Vehicle,
|
||||||
|
Engine,
|
||||||
|
Tracks,
|
||||||
|
Turret,
|
||||||
|
Gun,
|
||||||
|
}
|
||||||
|
|
||||||
export interface Unlock {
|
export interface Unlock {
|
||||||
type: ModuleType;
|
type: ModuleType;
|
||||||
id: number;
|
id: number;
|
||||||
@@ -32,9 +53,9 @@ export interface Unlock {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
export interface Crew {
|
export interface Crew {
|
||||||
type: CrewMember;
|
type: CrewType;
|
||||||
count?: number;
|
count?: number;
|
||||||
substitute?: CrewMember[];
|
substitute?: CrewType[];
|
||||||
}
|
}
|
||||||
export type ModuleDefinition =
|
export type ModuleDefinition =
|
||||||
| TrackDefinition
|
| TrackDefinition
|
||||||
@@ -45,18 +66,18 @@ export interface TankDefinition {
|
|||||||
id: number;
|
id: number;
|
||||||
roles: Record<number, number>;
|
roles: Record<number, number>;
|
||||||
description?: string;
|
description?: string;
|
||||||
fixedCamouflage?: boolean;
|
fixed_camouflage: boolean;
|
||||||
camouflages?: number[];
|
camouflages: number[];
|
||||||
ancestors?: number[];
|
ancestors: number[];
|
||||||
successors?: number[];
|
successors: number[];
|
||||||
crew: Crew[];
|
crew: Crew[];
|
||||||
health: number;
|
health: number;
|
||||||
nation: string;
|
nation: string;
|
||||||
name: string;
|
name: string;
|
||||||
nameFull?: string;
|
nameFull?: string;
|
||||||
treeType: TreeType;
|
type: TankType;
|
||||||
consumables: number;
|
max_consumables: number;
|
||||||
provisions: number;
|
max_provisions: number;
|
||||||
tier: Tier;
|
tier: Tier;
|
||||||
class: TankClass;
|
class: TankClass;
|
||||||
testing: boolean;
|
testing: boolean;
|
||||||
@@ -66,16 +87,12 @@ export interface TankDefinition {
|
|||||||
tracks: TrackDefinition[];
|
tracks: TrackDefinition[];
|
||||||
price: TankPrice;
|
price: TankPrice;
|
||||||
xp?: number;
|
xp?: number;
|
||||||
speed: {
|
speed_forwards: number;
|
||||||
forwards: number;
|
speed_backwards: number;
|
||||||
backwards: number;
|
camouflage_still: number;
|
||||||
};
|
camouflage_moving: number;
|
||||||
camouflage: {
|
camouflage_onFire: number;
|
||||||
still: number;
|
equipment_preset: string;
|
||||||
moving: number;
|
|
||||||
onFire: number;
|
|
||||||
};
|
|
||||||
equipment: string;
|
|
||||||
weight: number;
|
weight: number;
|
||||||
}
|
}
|
||||||
export interface TrackDefinition {
|
export interface TrackDefinition {
|
||||||
@@ -83,17 +100,13 @@ export interface TrackDefinition {
|
|||||||
tier: Tier;
|
tier: Tier;
|
||||||
name: string;
|
name: string;
|
||||||
weight: number;
|
weight: number;
|
||||||
traverseSpeed: number;
|
traverse_speed: number;
|
||||||
xp?: number;
|
xp?: number;
|
||||||
dispersion: {
|
dispersion_move: number;
|
||||||
move: number;
|
dispersion_traverse: number;
|
||||||
traverse: number;
|
resistance_hard: number;
|
||||||
};
|
resistance_medium: number;
|
||||||
resistance: {
|
resistance_soft: number;
|
||||||
hard: number;
|
|
||||||
medium: number;
|
|
||||||
soft: number;
|
|
||||||
};
|
|
||||||
unlocks?: Unlock[];
|
unlocks?: Unlock[];
|
||||||
}
|
}
|
||||||
export interface EngineDefinition {
|
export interface EngineDefinition {
|
||||||
@@ -101,18 +114,24 @@ export interface EngineDefinition {
|
|||||||
name: string;
|
name: string;
|
||||||
xp?: number;
|
xp?: number;
|
||||||
tier: Tier;
|
tier: Tier;
|
||||||
fireChance: number;
|
fire_chance: number;
|
||||||
power: number;
|
power: number;
|
||||||
weight: number;
|
weight: number;
|
||||||
unlocks?: Unlock[];
|
unlocks?: Unlock[];
|
||||||
}
|
}
|
||||||
export type TankPrice =
|
export type TankPrice = {
|
||||||
| { type: 'credits'; value: number }
|
type: TankPriceType;
|
||||||
| { type: 'gold'; value: number };
|
value: number;
|
||||||
|
};
|
||||||
|
enum TankPriceType {
|
||||||
|
Unspecified,
|
||||||
|
Credits,
|
||||||
|
Gold,
|
||||||
|
}
|
||||||
export interface TurretDefinition {
|
export interface TurretDefinition {
|
||||||
health: number;
|
health: number;
|
||||||
viewRange: number;
|
view_range: number;
|
||||||
traverseSpeed: number;
|
traverse_speed: number;
|
||||||
xp?: number;
|
xp?: number;
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -126,52 +145,60 @@ export type GunDefinition =
|
|||||||
| GunDefinitionAutoLoader
|
| GunDefinitionAutoLoader
|
||||||
| GunDefinitionAutoReloader;
|
| GunDefinitionAutoReloader;
|
||||||
interface GunDefinitionBase {
|
interface GunDefinitionBase {
|
||||||
rotationSpeed: number;
|
rotation_speed: number;
|
||||||
xp?: number;
|
xp?: number;
|
||||||
weight: number;
|
weight: number;
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
tier: Tier;
|
tier: Tier;
|
||||||
shells: ShellDefinition[];
|
shells: ShellDefinition[];
|
||||||
camouflageLoss: number;
|
camouflage_loss: number;
|
||||||
aimTime: number;
|
aim_time: number;
|
||||||
dispersion: {
|
dispersion_base: number;
|
||||||
base: number;
|
dispersion_traverse: number;
|
||||||
traverse: number;
|
dispersion_shot: number;
|
||||||
shot: number;
|
dispersion_damaged: number;
|
||||||
damaged: number;
|
|
||||||
};
|
|
||||||
unlocks?: Unlock[];
|
unlocks?: Unlock[];
|
||||||
}
|
}
|
||||||
interface GunDefinitionRegular extends GunDefinitionBase {
|
interface GunDefinitionRegular {
|
||||||
type: 'regular';
|
gun: GunDefinitionBase;
|
||||||
|
regular: GunDefinitionRegularProperties;
|
||||||
|
}
|
||||||
|
interface GunDefinitionRegularProperties {
|
||||||
reload: number;
|
reload: number;
|
||||||
}
|
}
|
||||||
interface GunDefinitionAutoLoader extends GunDefinitionBase {
|
interface GunDefinitionAutoLoader {
|
||||||
type: 'autoLoader';
|
gun: GunDefinitionBase;
|
||||||
|
auto_loader: GunDefinitionAutoLoaderProperties;
|
||||||
|
}
|
||||||
|
interface GunDefinitionAutoLoaderProperties {
|
||||||
reload: number;
|
reload: number;
|
||||||
intraClip: number;
|
intra_clip: number;
|
||||||
count: number;
|
count: number;
|
||||||
}
|
}
|
||||||
interface GunDefinitionAutoReloader extends GunDefinitionBase {
|
interface GunDefinitionAutoReloader {
|
||||||
type: 'autoReloader';
|
gun: GunDefinitionBase;
|
||||||
|
auto_reloader: GunDefinitionAutoReloaderProperties;
|
||||||
|
}
|
||||||
|
interface GunDefinitionAutoReloaderProperties {
|
||||||
reload: number[];
|
reload: number[];
|
||||||
intraClip: number;
|
intraClip: number;
|
||||||
count: number;
|
count: number;
|
||||||
}
|
}
|
||||||
export type ShellDefinition = {
|
export interface ShellDefinition {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
speed: number;
|
velocity: number;
|
||||||
damage: { armor: number; module: number };
|
armor_damage: number;
|
||||||
|
module_damage: number;
|
||||||
caliber: number;
|
caliber: number;
|
||||||
icon: string;
|
icon: string;
|
||||||
penetration: number | Vector2Tuple;
|
penetration: number | Vector2Tuple;
|
||||||
type: ShellType;
|
type: ShellType;
|
||||||
normalization?: number;
|
normalization?: number;
|
||||||
ricochet?: number;
|
ricochet?: number;
|
||||||
explosionRadius?: number;
|
explosion_radius?: number;
|
||||||
};
|
}
|
||||||
|
|
||||||
export const tankDefinitions = fetchCdonLz4<TankDefinitions>(
|
export const tankDefinitions = fetchCdonLz4<TankDefinitions>(
|
||||||
asset('definitions/tanks.cdon.lz4'),
|
asset('definitions/tanks.cdon.lz4'),
|
||||||
@@ -180,6 +207,18 @@ export const tankDefinitions = fetchCdonLz4<TankDefinitions>(
|
|||||||
export const tankDefinitionsArray = tankDefinitions.then((tanks) =>
|
export const tankDefinitionsArray = tankDefinitions.then((tanks) =>
|
||||||
Object.values(tanks),
|
Object.values(tanks),
|
||||||
);
|
);
|
||||||
export type Tier = (typeof TIERS)[number];
|
export enum Tier {
|
||||||
|
Unspecified,
|
||||||
|
I,
|
||||||
|
II,
|
||||||
|
III,
|
||||||
|
IV,
|
||||||
|
V,
|
||||||
|
VI,
|
||||||
|
VII,
|
||||||
|
VIII,
|
||||||
|
IX,
|
||||||
|
X,
|
||||||
|
}
|
||||||
|
|
||||||
export * from './constants';
|
export * from './constants';
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import protobuf from 'protobufjs';
|
import protobuf from 'protobufjs';
|
||||||
import average_definitions from '../../protos/average_definitions.proto?raw';
|
import average_definitions from '../../protos/average_definitions.proto';
|
||||||
import reviews from '../../protos/reviews.proto?raw';
|
import reviews from '../../protos/reviews.proto';
|
||||||
|
import tank_definitions from '../../protos/tank_definitions.proto';
|
||||||
|
|
||||||
export type ProtoSource = keyof typeof protos;
|
export type ProtoSource = keyof typeof protos;
|
||||||
|
|
||||||
const protos = { reviews, average_definitions };
|
const protos = { reviews, average_definitions, tank_definitions };
|
||||||
|
|
||||||
export function lookupProtobufType(source: ProtoSource, type: string) {
|
export function lookupProtobufType(source: ProtoSource, type: string) {
|
||||||
return protobuf.parse(protos[source]).root.lookupType(type);
|
return protobuf.parse(protos[source]).root.lookupType(type);
|
||||||
|
|||||||
@@ -1,375 +0,0 @@
|
|||||||
import { times } from 'lodash-es';
|
|
||||||
import { ReadStream, WriteStream } from './buffer';
|
|
||||||
|
|
||||||
enum ValueType {
|
|
||||||
Null,
|
|
||||||
Boolean,
|
|
||||||
Uint8,
|
|
||||||
Uint16,
|
|
||||||
Uint32,
|
|
||||||
Uint64,
|
|
||||||
Int8,
|
|
||||||
Int16,
|
|
||||||
Int32,
|
|
||||||
Int64,
|
|
||||||
Float32,
|
|
||||||
Float64,
|
|
||||||
String,
|
|
||||||
FastString,
|
|
||||||
Array,
|
|
||||||
Object,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum FastStringFormat {
|
|
||||||
Format8,
|
|
||||||
Format16,
|
|
||||||
Format32,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CdonValue =
|
|
||||||
| undefined
|
|
||||||
| null
|
|
||||||
| boolean
|
|
||||||
| number
|
|
||||||
| bigint
|
|
||||||
| string
|
|
||||||
| CdonValue[]
|
|
||||||
| { [key: string]: CdonValue };
|
|
||||||
|
|
||||||
export class CdonReadStream extends ReadStream {
|
|
||||||
cdon() {
|
|
||||||
this.magic();
|
|
||||||
const header = this.header();
|
|
||||||
const body = this.body(header.fastStringFormat, header.stringTable);
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
magic() {
|
|
||||||
const magic = this.utf8(4);
|
|
||||||
|
|
||||||
if (magic !== 'CDON') {
|
|
||||||
throw new Error(`Invalid CDON magic number: "${magic}"`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header() {
|
|
||||||
const version = this.uint16();
|
|
||||||
const fastStringFormat = this.uint8() as FastStringFormat;
|
|
||||||
|
|
||||||
return {
|
|
||||||
version,
|
|
||||||
fastStringFormat,
|
|
||||||
stringTable: this.stringTable(fastStringFormat),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
body(
|
|
||||||
fastStringFormat: FastStringFormat,
|
|
||||||
stringTable: Record<number, string>,
|
|
||||||
) {
|
|
||||||
return this.value(fastStringFormat, stringTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
stringTable(fastStringFormat: FastStringFormat) {
|
|
||||||
let count: number;
|
|
||||||
|
|
||||||
switch (fastStringFormat) {
|
|
||||||
case FastStringFormat.Format8:
|
|
||||||
count = this.uint8();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FastStringFormat.Format16:
|
|
||||||
count = this.uint16();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FastStringFormat.Format32:
|
|
||||||
count = this.uint32();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const strings: string[] = [];
|
|
||||||
|
|
||||||
for (let index = 0; index < count; index++) {
|
|
||||||
strings.push(this.string());
|
|
||||||
}
|
|
||||||
|
|
||||||
const table: Record<number, string> = {};
|
|
||||||
times(count, (index) => (table[index] = strings[index]));
|
|
||||||
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
string() {
|
|
||||||
const length = this.uint32();
|
|
||||||
const string = this.utf8(length);
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
value(
|
|
||||||
fastStringFormat: FastStringFormat,
|
|
||||||
stringTable: Record<number, string>,
|
|
||||||
): CdonValue {
|
|
||||||
const type = this.uint8() as ValueType;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case ValueType.Null:
|
|
||||||
return null;
|
|
||||||
|
|
||||||
case ValueType.Boolean:
|
|
||||||
return this.boolean();
|
|
||||||
|
|
||||||
case ValueType.Uint8:
|
|
||||||
return this.uint8();
|
|
||||||
|
|
||||||
case ValueType.Uint16:
|
|
||||||
return this.uint16();
|
|
||||||
|
|
||||||
case ValueType.Uint32:
|
|
||||||
return this.uint32();
|
|
||||||
|
|
||||||
case ValueType.Uint64:
|
|
||||||
return this.uint64();
|
|
||||||
|
|
||||||
case ValueType.Int8:
|
|
||||||
return this.int8();
|
|
||||||
|
|
||||||
case ValueType.Int16:
|
|
||||||
return this.int16();
|
|
||||||
|
|
||||||
case ValueType.Int32:
|
|
||||||
return this.int32();
|
|
||||||
|
|
||||||
case ValueType.Int64:
|
|
||||||
return this.int64();
|
|
||||||
|
|
||||||
case ValueType.Float32:
|
|
||||||
return this.float32();
|
|
||||||
|
|
||||||
case ValueType.Float64:
|
|
||||||
return this.float64();
|
|
||||||
|
|
||||||
case ValueType.String:
|
|
||||||
return this.string();
|
|
||||||
|
|
||||||
case ValueType.FastString: {
|
|
||||||
switch (fastStringFormat) {
|
|
||||||
case FastStringFormat.Format8:
|
|
||||||
return stringTable[this.uint8()];
|
|
||||||
|
|
||||||
case FastStringFormat.Format16:
|
|
||||||
return stringTable[this.uint16()];
|
|
||||||
|
|
||||||
case FastStringFormat.Format32:
|
|
||||||
return stringTable[this.uint32()];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case ValueType.Array:
|
|
||||||
return times(this.uint32(), () =>
|
|
||||||
this.value(fastStringFormat, stringTable),
|
|
||||||
);
|
|
||||||
|
|
||||||
case ValueType.Object: {
|
|
||||||
const count = this.uint32();
|
|
||||||
const keys = times(
|
|
||||||
count,
|
|
||||||
() => this.value(fastStringFormat, stringTable) as string,
|
|
||||||
);
|
|
||||||
const values = times(count, () =>
|
|
||||||
this.value(fastStringFormat, stringTable),
|
|
||||||
);
|
|
||||||
const object: Record<string, CdonValue> = {};
|
|
||||||
|
|
||||||
keys.forEach((string, index) => (object[string] = values[index]));
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new Error(`Invalid value type: ${type}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CdonWriteStream extends WriteStream {
|
|
||||||
cdon(object: CdonValue) {
|
|
||||||
this.magic();
|
|
||||||
const header = this.header(object);
|
|
||||||
this.body(header.fastStringFormat, object, header.stringTable);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
body(
|
|
||||||
fastStringFormat: FastStringFormat,
|
|
||||||
object: CdonValue,
|
|
||||||
stringTable: Map<string, number>,
|
|
||||||
) {
|
|
||||||
this.value(fastStringFormat, object, stringTable);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
value(
|
|
||||||
fastStringFormat: FastStringFormat,
|
|
||||||
object: CdonValue,
|
|
||||||
stringTable: Map<string, number>,
|
|
||||||
) {
|
|
||||||
if (object === null || object === undefined) {
|
|
||||||
this.uint8(ValueType.Null);
|
|
||||||
} else if (typeof object === 'boolean') {
|
|
||||||
this.uint8(ValueType.Boolean);
|
|
||||||
this.uint8(object ? 1 : 0);
|
|
||||||
} else if (typeof object === 'number') {
|
|
||||||
if (object % 1 === 0) {
|
|
||||||
if (object < 0) {
|
|
||||||
if (object < -0x80000000) {
|
|
||||||
this.uint8(ValueType.Int64);
|
|
||||||
this.int64(BigInt(object));
|
|
||||||
} else if (object < -0x8000) {
|
|
||||||
this.uint8(ValueType.Int32);
|
|
||||||
this.int32(object);
|
|
||||||
} else if (object < -0x80) {
|
|
||||||
this.uint8(ValueType.Int16);
|
|
||||||
this.int16(object);
|
|
||||||
} else {
|
|
||||||
this.uint8(ValueType.Int8);
|
|
||||||
this.int8(object);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (object > 0x7fffffff) {
|
|
||||||
this.uint8(ValueType.Uint64);
|
|
||||||
this.uint64(BigInt(object));
|
|
||||||
} else if (object > 0x7fff) {
|
|
||||||
this.uint8(ValueType.Uint32);
|
|
||||||
this.uint32(object);
|
|
||||||
} else if (object > 0x7f) {
|
|
||||||
this.uint8(ValueType.Uint16);
|
|
||||||
this.uint16(object);
|
|
||||||
} else {
|
|
||||||
this.uint8(ValueType.Uint8);
|
|
||||||
this.uint8(object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (object < -0x80000000 || object > 0x7fffffff) {
|
|
||||||
this.uint8(ValueType.Float64);
|
|
||||||
this.float64(object);
|
|
||||||
} else {
|
|
||||||
this.uint8(ValueType.Float32);
|
|
||||||
this.float32(object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (typeof object === 'bigint') {
|
|
||||||
if (object < 0) {
|
|
||||||
this.int64(object);
|
|
||||||
} else {
|
|
||||||
this.uint64(object);
|
|
||||||
}
|
|
||||||
} else if (typeof object === 'string') {
|
|
||||||
if (stringTable.has(object)) {
|
|
||||||
this.uint8(ValueType.FastString);
|
|
||||||
const id = stringTable.get(object)!;
|
|
||||||
switch (fastStringFormat) {
|
|
||||||
case FastStringFormat.Format8:
|
|
||||||
this.uint8(id);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FastStringFormat.Format16:
|
|
||||||
this.uint16(id);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FastStringFormat.Format32:
|
|
||||||
this.uint32(id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.uint8(ValueType.String);
|
|
||||||
this.string(object);
|
|
||||||
}
|
|
||||||
} else if (Array.isArray(object)) {
|
|
||||||
this.uint8(ValueType.Array);
|
|
||||||
this.uint32(object.length);
|
|
||||||
object.forEach((value) =>
|
|
||||||
this.value(fastStringFormat, value, stringTable),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const entries = Object.entries(object).filter(
|
|
||||||
([, value]) => value !== undefined,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.uint8(ValueType.Object);
|
|
||||||
this.uint32(entries.length);
|
|
||||||
entries.forEach(([key]) =>
|
|
||||||
this.value(fastStringFormat, key, stringTable),
|
|
||||||
);
|
|
||||||
entries.forEach(([, value]) =>
|
|
||||||
this.value(fastStringFormat, value, stringTable),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header(object: CdonValue) {
|
|
||||||
this.uint16(1);
|
|
||||||
return this.stringTable(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
stringTable(object: CdonValue) {
|
|
||||||
const stringTable = this.buildStringTable(
|
|
||||||
this.collectStringCounts(object, new Map()),
|
|
||||||
);
|
|
||||||
let fastStringFormat: FastStringFormat;
|
|
||||||
|
|
||||||
if (stringTable.size <= 0xff) {
|
|
||||||
fastStringFormat = FastStringFormat.Format8;
|
|
||||||
this.uint8(FastStringFormat.Format8);
|
|
||||||
this.uint8(stringTable.size);
|
|
||||||
} else if (stringTable.size <= 0xffff) {
|
|
||||||
fastStringFormat = FastStringFormat.Format16;
|
|
||||||
this.uint8(FastStringFormat.Format16);
|
|
||||||
this.uint16(stringTable.size);
|
|
||||||
} else {
|
|
||||||
fastStringFormat = FastStringFormat.Format32;
|
|
||||||
this.uint8(FastStringFormat.Format32);
|
|
||||||
this.uint32(stringTable.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
stringTable.forEach((_index, string) => this.string(string));
|
|
||||||
|
|
||||||
return { fastStringFormat, stringTable };
|
|
||||||
}
|
|
||||||
|
|
||||||
buildStringTable(stringCounts: Map<string, number>) {
|
|
||||||
const stringTable = new Map<string, number>();
|
|
||||||
|
|
||||||
stringCounts.forEach((count, string) => {
|
|
||||||
if (count > 1) stringTable.set(string, stringTable.size);
|
|
||||||
});
|
|
||||||
|
|
||||||
return stringTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
collectStringCounts(object: CdonValue, stringCounts: Map<string, number>) {
|
|
||||||
if (typeof object === 'string') {
|
|
||||||
if (stringCounts.has(object)) {
|
|
||||||
stringCounts.set(object, stringCounts.get(object)! + 1);
|
|
||||||
} else {
|
|
||||||
stringCounts.set(object, 1);
|
|
||||||
}
|
|
||||||
} else if (object instanceof Array) {
|
|
||||||
object.forEach((value) => this.collectStringCounts(value, stringCounts));
|
|
||||||
} else if (object instanceof Object) {
|
|
||||||
Object.entries(object).forEach((strings) =>
|
|
||||||
this.collectStringCounts(strings, stringCounts),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringCounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
string(value: string) {
|
|
||||||
this.uint32(Buffer.byteLength(value));
|
|
||||||
this.utf8(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
magic() {
|
|
||||||
this.utf8('CDON');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
export * from './bkrl';
|
export * from './bkrl';
|
||||||
export * from './buffer';
|
export * from './buffer';
|
||||||
export * from './cdon';
|
|
||||||
export * from './dds';
|
export * from './dds';
|
||||||
export * from './dids';
|
export * from './dids';
|
||||||
export * from './pvr';
|
export * from './pvr';
|
||||||
|
|||||||
@@ -807,7 +807,7 @@ export async function definitions() {
|
|||||||
forwards: tankDefinition.root.speedLimits.forward,
|
forwards: tankDefinition.root.speedLimits.forward,
|
||||||
backwards: tankDefinition.root.speedLimits.backward,
|
backwards: tankDefinition.root.speedLimits.backward,
|
||||||
},
|
},
|
||||||
equipment:
|
equipment_preset:
|
||||||
typeof equipment === 'string' ? equipment : equipment.at(-1)!,
|
typeof equipment === 'string' ? equipment : equipment.at(-1)!,
|
||||||
consumables: tankDefinition.root.consumableSlots,
|
consumables: tankDefinition.root.consumableSlots,
|
||||||
provisions: tankDefinition.root.provisionSlots,
|
provisions: tankDefinition.root.provisionSlots,
|
||||||
@@ -888,7 +888,7 @@ export async function definitions() {
|
|||||||
id: trackId,
|
id: trackId,
|
||||||
weight: track.weight,
|
weight: track.weight,
|
||||||
name: strings[track.userString],
|
name: strings[track.userString],
|
||||||
traverseSpeed: track.rotationSpeed,
|
traverse_speed: track.rotationSpeed,
|
||||||
dispersion: {
|
dispersion: {
|
||||||
move: track.shotDispersionFactors.vehicleMovement,
|
move: track.shotDispersionFactors.vehicleMovement,
|
||||||
traverse: track.shotDispersionFactors.vehicleRotation,
|
traverse: track.shotDispersionFactors.vehicleRotation,
|
||||||
@@ -920,7 +920,7 @@ export async function definitions() {
|
|||||||
tankDefinitions[tankId].engines.push({
|
tankDefinitions[tankId].engines.push({
|
||||||
id: engineId,
|
id: engineId,
|
||||||
name: strings[engineListEntry.userString],
|
name: strings[engineListEntry.userString],
|
||||||
fireChance: engineListEntry.fireStartingChance,
|
fire_chance: engineListEntry.fireStartingChance,
|
||||||
tier: engineListEntry.level as Tier,
|
tier: engineListEntry.level as Tier,
|
||||||
weight: engineListEntry.weight,
|
weight: engineListEntry.weight,
|
||||||
power: engineListEntry.power,
|
power: engineListEntry.power,
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { $ } from 'bun';
|
||||||
|
import { readdir } from 'fs/promises';
|
||||||
|
|
||||||
|
const ROOT = 'packages/core/protos';
|
||||||
|
|
||||||
|
const files = await readdir(`${ROOT}/raw`);
|
||||||
|
const args = [
|
||||||
|
'--plugin="./node_modules/.bin/protoc-gen-ts"',
|
||||||
|
'--js_out="import_style=commonjs,binary:${OUT_DIR}"',
|
||||||
|
`--ts_out="${ROOT}/generated"`,
|
||||||
|
...files.map((file) => `${ROOT}/raw/${file}`),
|
||||||
|
];
|
||||||
|
|
||||||
|
console.log(`protoc ${args.join(' ')}`);
|
||||||
|
|
||||||
|
console.log(await $`protoc ${args.join(' ')}`.text());
|
||||||
Reference in new issue
Block a user