octane 0.12.0 → 0.13.0
raw patch · 53 files changed
+1814/−1732 lines, 53 filesdep +file-embeddep +regex-compat
Dependencies added: file-embed, regex-compat
Files
- README.markdown +1/−1
- data/classes-with-location.json +18/−0
- data/classes-with-rotation.json +5/−0
- data/classes.json +36/−0
- data/game-modes.json +5/−0
- data/products.json +845/−0
- data/properties.json +128/−0
- library/Octane/Data.hs +67/−26
- library/Octane/Data/Antennas.hs +0/−435
- library/Octane/Data/Bodies.hs +0/−33
- library/Octane/Data/Bots.hs +0/−66
- library/Octane/Data/Classes.hs +0/−179
- library/Octane/Data/Decals.hs +0/−220
- library/Octane/Data/Finishes.hs +0/−28
- library/Octane/Data/GameModes.hs +0/−15
- library/Octane/Data/Logos.hs +0/−33
- library/Octane/Data/Properties.hs +0/−294
- library/Octane/Data/RocketTrails.hs +0/−63
- library/Octane/Data/Toppers.hs +0/−78
- library/Octane/Data/Wheels.hs +0/−51
- library/Octane/Type.hs +2/−0
- library/Octane/Type/Boolean.hs +19/−0
- library/Octane/Type/CacheItem.hs +9/−0
- library/Octane/Type/CacheProperty.hs +6/−0
- library/Octane/Type/ClassItem.hs +6/−0
- library/Octane/Type/Dictionary.hs +20/−1
- library/Octane/Type/Float32.hs +20/−2
- library/Octane/Type/Frame.hs +16/−42
- library/Octane/Type/Initialization.hs +3/−0
- library/Octane/Type/Int32.hs +16/−2
- library/Octane/Type/Int8.hs +21/−0
- library/Octane/Type/KeyFrame.hs +6/−0
- library/Octane/Type/List.hs +33/−2
- library/Octane/Type/Mark.hs +6/−0
- library/Octane/Type/Message.hs +6/−0
- library/Octane/Type/RemoteId.hs +189/−18
- library/Octane/Type/Replication.hs +3/−0
- library/Octane/Type/Stream.hs +10/−0
- library/Octane/Type/Text.hs +44/−3
- library/Octane/Type/Value.hs +1/−4
- library/Octane/Type/Vector.hs +7/−0
- library/Octane/Type/Word16.hs +11/−1
- library/Octane/Type/Word32.hs +20/−2
- library/Octane/Type/Word64.hs +21/−3
- library/Octane/Type/Word8.hs +21/−0
- library/Octane/Utility.hs +4/−0
- library/Octane/Utility/CRC.hs +2/−2
- library/Octane/Utility/ClassPropertyMap.hs +50/−16
- library/Octane/Utility/Embed.hs +58/−0
- library/Octane/Utility/Endian.hs +6/−0
- library/Octane/Utility/Parser.hs +59/−98
- octane.cabal +10/−13
- package.yaml +4/−1
README.markdown view
@@ -39,7 +39,7 @@ [Octane]: https://github.com/tfausak/octane [Version badge]: https://www.stackage.org/package/octane/badge/nightly?label=version-[version]: https://www.stackage.org/package/octane+[version]: https://www.stackage.org/nightly/package/octane [Windows build badge]: https://ci.appveyor.com/api/projects/status/github/tfausak/octane?branch=main&svg=true [windows build]: https://ci.appveyor.com/project/TaylorFausak/octane [Build badge]: https://travis-ci.org/tfausak/octane.svg?branch=main
+ data/classes-with-location.json view
@@ -0,0 +1,18 @@+[+ "TAGame.Ball_TA",+ "TAGame.CameraSettingsActor_TA",+ "TAGame.Car_Season_TA",+ "TAGame.Car_TA",+ "TAGame.CarComponent_Boost_TA",+ "TAGame.CarComponent_Dodge_TA",+ "TAGame.CarComponent_DoubleJump_TA",+ "TAGame.CarComponent_FlipCar_TA",+ "TAGame.CarComponent_Jump_TA",+ "TAGame.GameEvent_Season_TA",+ "TAGame.GameEvent_Soccar_TA",+ "TAGame.GameEvent_SoccarPrivate_TA",+ "TAGame.GameEvent_SoccarSplitscreen_TA",+ "TAGame.GRI_TA",+ "TAGame.PRI_TA",+ "TAGame.Team_Soccar_TA"+]
+ data/classes-with-rotation.json view
@@ -0,0 +1,5 @@+[+ "TAGame.Ball_TA",+ "TAGame.Car_Season_TA",+ "TAGame.Car_TA"+]
+ data/classes.json view
@@ -0,0 +1,36 @@+{+ "Archetypes.Ball.Ball_Basketball": "TAGame.Ball_TA",+ "Archetypes.Ball.Ball_Default": "TAGame.Ball_TA",+ "Archetypes.Ball.Ball_Puck": "TAGame.Ball_TA",+ "Archetypes.Ball.CubeBall": "TAGame.Ball_TA",+ "Archetypes.Car.Car_Default": "TAGame.Car_TA",+ "Archetypes.CarComponents.CarComponent_Boost": "TAGame.CarComponent_Boost_TA",+ "Archetypes.CarComponents.CarComponent_Dodge": "TAGame.CarComponent_Dodge_TA",+ "Archetypes.CarComponents.CarComponent_DoubleJump": "TAGame.CarComponent_DoubleJump_TA",+ "Archetypes.CarComponents.CarComponent_FlipCar": "TAGame.CarComponent_FlipCar_TA",+ "Archetypes.CarComponents.CarComponent_Jump": "TAGame.CarComponent_Jump_TA",+ "Archetypes.GameEvent.GameEvent_Basketball": "TAGame.GameEvent_Soccar_TA",+ "Archetypes.GameEvent.GameEvent_BasketballPrivate": "TAGame.GameEvent_SoccarPrivate_TA",+ "Archetypes.GameEvent.GameEvent_BasketballSplitscreen": "TAGame.GameEvent_SoccarSplitscreen_TA",+ "Archetypes.GameEvent.GameEvent_HockeyPrivate": "TAGame.GameEvent_SoccarPrivate_TA",+ "Archetypes.GameEvent.GameEvent_HockeySplitscreen": "TAGame.GameEvent_SoccarSplitscreen_TA",+ "Archetypes.GameEvent.GameEvent_Season:CarArchetype": "TAGame.Car_TA",+ "Archetypes.GameEvent.GameEvent_Season": "TAGame.GameEvent_Season_TA",+ "Archetypes.GameEvent.GameEvent_Soccar": "TAGame.GameEvent_Soccar_TA",+ "Archetypes.GameEvent.GameEvent_SoccarPrivate": "TAGame.GameEvent_SoccarPrivate_TA",+ "Archetypes.GameEvent.GameEvent_SoccarSplitscreen": "TAGame.GameEvent_SoccarSplitscreen_TA",+ "Archetypes.Teams.Team0": "TAGame.Team_Soccar_TA",+ "Archetypes.Teams.Team1": "TAGame.Team_Soccar_TA",+ "GameInfo_Basketball.GameInfo.GameInfo_Basketball:GameReplicationInfoArchetype": "TAGame.GRI_TA",+ "Gameinfo_Hockey.GameInfo.Gameinfo_Hockey:GameReplicationInfoArchetype": "TAGame.GRI_TA",+ "GameInfo_Season.GameInfo.GameInfo_Season:GameReplicationInfoArchetype": "TAGame.GRI_TA",+ "GameInfo_Soccar.GameInfo.GameInfo_Soccar:GameReplicationInfoArchetype": "TAGame.GRI_TA",+ "TAGame.CameraSettingsActor_TA:PRI": "TAGame.CameraSettingsActor_TA",+ "TAGame.Default__CameraSettingsActor_TA": "TAGame.CameraSettingsActor_TA",+ "TAGame.Default__PRI_TA": "TAGame.PRI_TA",+ "TAGame.Default__VoteActor_TA": "TAGame.VoteActor_TA",+ "TheWorld:PersistentLevel.CrowdActor_TA": "TAGame.CrowdActor_TA",+ "TheWorld:PersistentLevel.CrowdManager_TA": "TAGame.CrowdManager_TA",+ "TheWorld:PersistentLevel.InMapScoreboard_TA": "TAGame.InMapScoreboard_TA",+ "TheWorld:PersistentLevel.VehiclePickup_Boost_TA": "TAGame.VehiclePickup_Boost_TA"+}
+ data/game-modes.json view
@@ -0,0 +1,5 @@+{+ "Soccar": 0,+ "Hockey": 1,+ "Hoops": 2+}
+ data/products.json view
@@ -0,0 +1,845 @@+{+ "Antenna_8Ball": 1,+ "Antenna_Alien": 753,+ "Antenna_Blacklight": 385,+ "Antenna_Bomb": 614,+ "Antenna_Bread": 391,+ "Antenna_Candle": 757,+ "Antenna_CandyCane": 649,+ "Antenna_ChickMagnet": 392,+ "Antenna_ChristmasGift": 650,+ "Antenna_Cupcake": 393,+ "Antenna_DiscoBall": 800,+ "Antenna_Disconnected": 394,+ "Antenna_DLZ": 1351,+ "Antenna_DogBalloon": 752,+ "Antenna_DollarSign": 3,+ "Antenna_Donut": 395,+ "Antenna_DOTDSkull": 574,+ "Antenna_ETS2": 813,+ "Antenna_Eyeball": 396,+ "Antenna_Fallout_VaultBoy": 673,+ "Antenna_FlakShell": 397,+ "Antenna_Flower_Rose": 785,+ "Antenna_Flower_Sunflower": 786,+ "Antenna_Flower_Venus": 788,+ "Antenna_FoamFinger": 398,+ "Antenna_FurballFrakenstein": 593,+ "Antenna_FurballVampire": 595,+ "Antenna_GenieLamp": 798,+ "Antenna_Gingerbread_Man": 5,+ "Antenna_GoatSimulator_G2Robot": 927,+ "Antenna_GoatSimulator_Goat": 867,+ "Antenna_GoldNugget": 6,+ "Antenna_Heart": 7,+ "Antenna_Horseshoe": 8,+ "Antenna_HulaGirl": 762,+ "Antenna_LightningBolt": 9,+ "Antenna_Mau5": 781,+ "Antenna_Moai": 522,+ "Antenna_Parrot": 750,+ "Antenna_PeaceSign": 11,+ "Antenna_Pinata": 400,+ "Antenna_RadiationSymbol": 615,+ "Antenna_RedditSnoo": 629,+ "Antenna_Rocket": 755,+ "Antenna_RubberDuckie": 779,+ "Antenna_Saturn": 12,+ "Antenna_Skull": 13,+ "Antenna_SmileyFace": 14,+ "Antenna_Snowman": 15,+ "Antenna_SoccerBall": 16,+ "Antenna_SpartanSam": 1169,+ "Antenna_Star": 17,+ "Antenna_SweetTooth": 18,+ "Antenna_TennisBall": 19,+ "Antenna_UFO": 20,+ "Antenna_UrbanBall": 575,+ "Antenna_UtopiaBall": 576,+ "Antenna_VGA_Statue": 655,+ "Antenna_Waffle": 401,+ "Antenna_WastelandBall": 577,+ "Antenna_Witcher3_Medallion": 749,+ "Antenna_Worms_Grenade": 1000,+ "AT_GladOS_Potato": 698,+ "AT_Oddworld_Abe": 678,+ "AT_Oddworld_Glukkon": 679,+ "AT_Portal_PC": 686,+ "AT_PortalCube": 681,+ "AT_Warframe_Chroma": 682,+ "AT_Warframe_Excalibur": 684,+ "AT_Warframe_Loki": 683,+ "Body_Aftershock": 1286,+ "Body_Backfire": 21,+ "Body_Darkcar": 803,+ "Body_Force": 22,+ "Body_GearsCar": 625,+ "Body_GreyCar": 597,+ "Body_Import": 402,+ "Body_Interceptor": 600,+ "Body_Marauder": 1172,+ "Body_MuscleCar": 403,+ "Body_NeoBike": 1317,+ "Body_NeoCar": 1171,+ "Body_Octane": 23,+ "Body_Orion": 24,+ "Body_Rhino": 25,+ "Body_Scarab": 404,+ "Body_Spark": 26,+ "Body_SweetTooth": 27,+ "Body_Torch": 28,+ "Body_Torment": 29,+ "Body_Vanquish": 30,+ "Body_Venom": 31,+ "Body_Warthog": 723,+ "Body_WastelandTruck": 607,+ "Body_Zippy": 523,+ "Boost_AlphaReward": 32,+ "Boost_Bubble": 33,+ "Boost_Burnout": 387,+ "Boost_CandyCorn": 578,+ "Boost_Challenger": 1334,+ "Boost_Champion": 1335,+ "Boost_Confetti": 34,+ "Boost_ConversionGel": 651,+ "Boost_DarkCar": 868,+ "Boost_Digital": 35,+ "Boost_Flamethrower_Blue": 37,+ "Boost_Flamethrower_Green": 38,+ "Boost_Flamethrower_Pink": 39,+ "Boost_Flamethrower_Purple": 40,+ "Boost_Flamethrower_Red": 41,+ "Boost_Flamethrower_Yellow": 1318,+ "Boost_Flamethrower": 36,+ "Boost_Flowers": 42,+ "Boost_GoW_Imulsion": 729,+ "Boost_Grass": 43,+ "Boost_GreyCar": 626,+ "Boost_Hearts": 1091,+ "Boost_HolyLight": 44,+ "boost_iceshards": 1166,+ "Boost_Lightning": 405,+ "Boost_LightTrail_Green": 46,+ "Boost_LightTrail_Pink": 47,+ "Boost_LightTrail_Purple": 48,+ "Boost_LightTrail_Red": 49,+ "Boost_LightTrail_Yellow": 50,+ "Boost_LightTrail": 45,+ "Boost_Money": 51,+ "Boost_MusicalNotes": 524,+ "Boost_Needler": 715,+ "Boost_Nitrous": 384,+ "Boost_NutsBolts": 544,+ "Boost_Overcharge": 714,+ "Boost_Plasma": 52,+ "Boost_Presents": 635,+ "Boost_Propulsion_Blue": 54,+ "Boost_Propulsion_Green": 55,+ "Boost_Propulsion_Pink": 56,+ "Boost_Propulsion_Purple": 57,+ "Boost_Propulsion_Yellow": 58,+ "Boost_Propulsion": 53,+ "Boost_PropulsionGel": 652,+ "Boost_Prospect": 1336,+ "Boost_Rainbow": 59,+ "Boost_RepulsionGel": 653,+ "Boost_SandStorm": 664,+ "Boost_Slime": 60,+ "Boost_Snow": 61,+ "Boost_Sparkles": 62,+ "Boost_Standard_Blue": 64,+ "Boost_Standard_Green": 1319,+ "Boost_Standard_Pink": 65,+ "Boost_Standard_Purple": 66,+ "Boost_Standard_Yellow": 67,+ "Boost_Standard": 63,+ "Boost_Star": 1337,+ "Boost_Stars": 545,+ "Boost_SweetTooth": 68,+ "Boost_Toon": 1094,+ "Boost_UVGun": 718,+ "Boost_Water": 69,+ "Bot_Astro": 70,+ "Bot_Bane": 71,+ "Bot_Beast": 72,+ "Bot_Blade": 73,+ "Bot_C-Block": 74,+ "Bot_Captain": 75,+ "Bot_Caveman": 76,+ "Bot_Cougar": 77,+ "Bot_Devil": 78,+ "Bot_Diesel": 79,+ "Bot_Dotty": 80,+ "Bot_Dude": 81,+ "Bot_Duke": 82,+ "Bot_Dynamite": 83,+ "Bot_Flame": 84,+ "Bot_Flash": 85,+ "Bot_Fossil": 86,+ "Bot_Fury": 87,+ "Bot_Hawk": 88,+ "Bot_Hunter": 89,+ "Bot_Imp": 90,+ "Bot_Jet": 91,+ "Bot_JM": 92,+ "Bot_Kidd": 93,+ "Bot_Laser": 94,+ "Bot_Lightning": 95,+ "Bot_Lucky": 96,+ "Bot_Middy": 97,+ "Bot_Mountain": 98,+ "Bot_Nitro": 99,+ "Bot_Outlaw": 100,+ "Bot_Phoenix": 101,+ "Bot_Raja": 102,+ "Bot_Razor": 103,+ "Bot_Retro": 104,+ "Bot_Roundhouse": 105,+ "Bot_Sabre": 106,+ "Bot_Samson": 107,+ "Bot_Savage": 108,+ "Bot_Shadow": 109,+ "Bot_Shield": 110,+ "Bot_Siren": 111,+ "Bot_Sky": 112,+ "Bot_Squall": 113,+ "Bot_Tank": 114,+ "Bot_Thunder": 115,+ "Bot_Titan": 116,+ "Bot_Turbo": 117,+ "Bot_Tusk": 118,+ "Bot_Viper": 119,+ "Bot_Warrior": 120,+ "Bot_Wolf": 121,+ "Bot_Yuri": 122,+ "Bot_Zap": 123,+ "CountryFlag_Afganistan": 407,+ "CountryFlag_Albania": 408,+ "CountryFlag_Algeria": 124,+ "CountryFlag_American_Samoa": 409,+ "CountryFlag_Andorra": 830,+ "CountryFlag_Angola": 410,+ "CountryFlag_Anguilla": 831,+ "CountryFlag_Antigua": 832,+ "CountryFlag_Argentina": 125,+ "CountryFlag_Armenia": 411,+ "CountryFlag_Aruba": 833,+ "CountryFlag_Australia": 126,+ "CountryFlag_Austria": 127,+ "CountryFlag_Azerbaijan": 412,+ "CountryFlag_Bahamas": 834,+ "CountryFlag_Bahrain": 550,+ "CountryFlag_Bangladesh": 413,+ "CountryFlag_Barbados": 835,+ "CountryFlag_Belarus": 414,+ "CountryFlag_Belgium": 128,+ "CountryFlag_Belize": 551,+ "CountryFlag_Benin": 415,+ "CountryFlag_Bermuda": 836,+ "CountryFlag_Bhutan": 552,+ "CountryFlag_Bolivia": 416,+ "CountryFlag_Bosnia": 129,+ "CountryFlag_Botswana": 553,+ "CountryFlag_Brazil": 130,+ "CountryFlag_Bulgaria": 131,+ "CountryFlag_Burkina_Faso": 417,+ "CountryFlag_Burma": 418,+ "CountryFlag_Burundi": 419,+ "CountryFlag_BVE": 837,+ "CountryFlag_Cambodia": 420,+ "CountryFlag_Cameroon": 132,+ "CountryFlag_Canada": 133,+ "CountryFlag_Cape_Verde": 134,+ "CountryFlag_CAR": 520,+ "CountryFlag_CaymanIslands": 838,+ "CountryFlag_Chad": 422,+ "CountryFlag_Chile": 135,+ "CountryFlag_China": 136,+ "CountryFlag_Columbia": 137,+ "CountryFlag_Comoros": 554,+ "CountryFlag_Congo_DR": 423,+ "CountryFlag_Congo": 138,+ "CountryFlag_CookIslands": 839,+ "CountryFlag_CostaRica": 139,+ "CountryFlag_Croatia": 140,+ "CountryFlag_Cuba": 424,+ "CountryFlag_Curacao": 840,+ "CountryFlag_Cyprus": 141,+ "CountryFlag_CzechRepublic": 142,+ "CountryFlag_Denmark": 143,+ "CountryFlag_Djibouti": 555,+ "CountryFlag_Dominica": 841,+ "CountryFlag_Dominican_Republic": 425,+ "CountryFlag_EastTimor": 556,+ "CountryFlag_Ecuador": 144,+ "CountryFlag_Egypt": 426,+ "CountryFlag_El_Salvador": 145,+ "CountryFlag_England": 146,+ "CountryFlag_Equatorial_Guinea": 147,+ "CountryFlag_Eritrea": 427,+ "CountryFlag_Estonia": 428,+ "CountryFlag_Ethiopia": 429,+ "CountryFlag_FalklandIslands": 842,+ "CountryFlag_FaroeIslands": 843,+ "CountryFlag_Fiji": 557,+ "CountryFlag_Finland": 148,+ "CountryFlag_France": 149,+ "CountryFlag_Gabon": 430,+ "CountryFlag_Gambia": 558,+ "CountryFlag_Georgia": 431,+ "CountryFlag_Germany": 150,+ "CountryFlag_Ghana": 151,+ "CountryFlag_Gibraltar": 844,+ "CountryFlag_Greece": 152,+ "CountryFlag_Grenada": 863,+ "CountryFlag_Guam": 432,+ "CountryFlag_Guatemala": 153,+ "CountryFlag_Guinea": 154,+ "CountryFlag_GuineaBissau": 559,+ "CountryFlag_Guyana": 560,+ "CountryFlag_Haiti": 433,+ "CountryFlag_Honduras": 155,+ "CountryFlag_Hong_Kong": 156,+ "CountryFlag_Hungary": 157,+ "CountryFlag_Iceland": 158,+ "CountryFlag_India": 159,+ "CountryFlag_Indonesia": 160,+ "CountryFlag_Iran": 161,+ "CountryFlag_Iraq": 434,+ "CountryFlag_Ireland": 162,+ "CountryFlag_IsleOfMan": 845,+ "CountryFlag_Israel": 163,+ "CountryFlag_Italy": 164,+ "CountryFlag_IvoryCoast": 165,+ "CountryFlag_Jamaica": 166,+ "CountryFlag_Japan": 167,+ "CountryFlag_Jordan": 435,+ "CountryFlag_Kazakhstan": 436,+ "CountryFlag_Kenya": 168,+ "CountryFlag_Kiribati": 846,+ "CountryFlag_Kosovo": 561,+ "CountryFlag_Kuwait": 437,+ "CountryFlag_Kyrgystan": 438,+ "CountryFlag_Laos": 439,+ "CountryFlag_Latvia": 440,+ "CountryFlag_Lebanon": 441,+ "CountryFlag_Lesotho": 562,+ "CountryFlag_Liberia": 442,+ "CountryFlag_Libya": 443,+ "CountryFlag_Lithuania": 444,+ "CountryFlag_Luxembourg": 169,+ "CountryFlag_Macau": 563,+ "CountryFlag_Macedonia": 445,+ "CountryFlag_Madagascar": 446,+ "CountryFlag_Malawi": 447,+ "CountryFlag_Malaysia": 170,+ "CountryFlag_Maldives": 847,+ "CountryFlag_Mali": 448,+ "CountryFlag_Malta": 171,+ "CountryFlag_MarshallIslands": 848,+ "CountryFlag_Mauritania": 449,+ "CountryFlag_Mauritius": 564,+ "CountryFlag_Mexico": 172,+ "CountryFlag_Micronesia": 849,+ "CountryFlag_Moldova": 450,+ "CountryFlag_Mongolia": 451,+ "CountryFlag_Montenegro": 452,+ "CountryFlag_Montserrat": 864,+ "CountryFlag_Morocco": 453,+ "CountryFlag_Mozambique": 454,+ "CountryFlag_N_Mariana_Islands": 456,+ "CountryFlag_Namibia": 457,+ "CountryFlag_Nepal": 458,+ "CountryFlag_Netherlands": 173,+ "CountryFlag_New_Zealand": 174,+ "CountryFlag_NewCaledonia": 850,+ "CountryFlag_Nicaragua": 175,+ "CountryFlag_Niger": 459,+ "CountryFlag_Nigeria": 176,+ "CountryFlag_Northern_Ireland": 177,+ "CountryFlag_NorthKorea": 460,+ "CountryFlag_Norway": 178,+ "CountryFlag_Oman": 461,+ "CountryFlag_Pakistan": 179,+ "CountryFlag_Palau": 851,+ "CountryFlag_Palestine": 462,+ "CountryFlag_Panama": 180,+ "CountryFlag_Papua_NewGuinea": 463,+ "CountryFlag_Paraguay": 464,+ "CountryFlag_Peru": 181,+ "CountryFlag_Philippines": 182,+ "CountryFlag_Poland": 183,+ "CountryFlag_Portugal": 184,+ "CountryFlag_Puerto_Rico": 465,+ "CountryFlag_Puntland": 565,+ "CountryFlag_Qatar": 466,+ "CountryFlag_Reunion": 566,+ "CountryFlag_Romania": 185,+ "CountryFlag_Russia": 186,+ "CountryFlag_Rwanda": 467,+ "CountryFlag_SaintKitts": 852,+ "CountryFlag_SaintLucia": 853,+ "CountryFlag_SaintVincent": 854,+ "CountryFlag_Samoa": 855,+ "CountryFlag_SanMarino": 856,+ "CountryFlag_SaoTome": 857,+ "CountryFlag_Saudi_Arabia": 468,+ "CountryFlag_Scotland": 187,+ "CountryFlag_Senegal": 188,+ "CountryFlag_Serbia": 189,+ "CountryFlag_Seychelles": 858,+ "CountryFlag_Sierra_Leone": 469,+ "CountryFlag_Singapore": 190,+ "CountryFlag_Slovakia": 191,+ "CountryFlag_Slovenia": 192,+ "CountryFlag_SolomonIslands": 567,+ "CountryFlag_Somalia": 470,+ "CountryFlag_Somaliland": 568,+ "CountryFlag_South_Sudan": 471,+ "CountryFlag_SouthAfrica": 193,+ "CountryFlag_SouthKorea": 194,+ "CountryFlag_Spain": 195,+ "CountryFlag_Sri_Lanka": 389,+ "CountryFlag_Sudan": 472,+ "CountryFlag_Suriname": 569,+ "CountryFlag_Swaziland": 570,+ "CountryFlag_Sweden": 196,+ "CountryFlag_Switzerland": 197,+ "CountryFlag_Syria": 473,+ "CountryFlag_Tahiti": 859,+ "CountryFlag_Taiwan": 198,+ "CountryFlag_Tajikistan": 474,+ "CountryFlag_Tanzania": 475,+ "CountryFlag_Thailand": 199,+ "CountryFlag_Togo": 476,+ "CountryFlag_Tonga": 730,+ "CountryFlag_Trinidad_Tobago": 477,+ "CountryFlag_Tunisia": 200,+ "CountryFlag_Turkey": 201,+ "CountryFlag_Turkmenistan": 478,+ "CountryFlag_TurksCacos": 860,+ "CountryFlag_UAE": 202,+ "CountryFlag_Uganda": 479,+ "CountryFlag_UK": 203,+ "CountryFlag_Ukraine": 204,+ "CountryFlag_Uruguay": 205,+ "CountryFlag_US_Virgin_Islands": 480,+ "CountryFlag_USA": 206,+ "CountryFlag_Uzbekistan": 481,+ "CountryFlag_Vanuatu": 861,+ "CountryFlag_VaticanCity": 862,+ "CountryFlag_Venezuela": 207,+ "CountryFlag_Vietnam": 208,+ "CountryFlag_Wales": 209,+ "CountryFlag_WesternSahara": 571,+ "CountryFlag_Yemen": 210,+ "CountryFlag_Zambia": 482,+ "CountryFlag_Zimbabwe": 483,+ "Crown_Bronze": 705,+ "Crown_Gold": 706,+ "Crown_Platinum": 707,+ "Crown_Silver": 708,+ "Flag_4PlayerNetwork": 1212,+ "Flag_9Gag": 799,+ "Flag_AbleGamers": 814,+ "flag_atlanta_hawks": 1245,+ "Flag_Batman": 804,+ "Flag_BlacklightRetribution": 211,+ "flag_boston_celtics": 1246,+ "flag_brooklyn_nets": 1247,+ "flag_charlotte_hornets": 1248,+ "flag_chicago_bulls": 1249,+ "Flag_Chivalry_Agatha": 525,+ "Flag_Chivalry_Mason": 526,+ "flag_cleveland_cavaliers": 1250,+ "Flag_Community": 527,+ "flag_dallas_mavericks": 1251,+ "Flag_Day9TV": 654,+ "flag_denver_nuggets": 1252,+ "Flag_Destructoid": 724,+ "flag_detroit_pistons": 1253,+ "Flag_DyingLight": 1304,+ "Flag_EdgeOfSpace": 213,+ "Flag_Epic_BlueFlag": 484,+ "Flag_Epic_FragCenter": 485,+ "Flag_Epic_RedFlag": 486,+ "Flag_Epic_UT": 487,+ "Flag_Epic_UT2004": 488,+ "Flag_Epic_UTBlue": 489,+ "Flag_FenixRage": 216,+ "Flag_Gamespot": 725,+ "Flag_Gfinity": 732,+ "flag_goldenstate_warriors": 1254,+ "Flag_GoldGlove": 728,+ "flag_houston_rockets": 1255,+ "Flag_IGN": 802,+ "flag_indiana_pacers": 1256,+ "flag_la_clippers": 1257,+ "flag_la_lakers": 1258,+ "flag_memphis_grizzlies": 1259,+ "flag_miami_heat": 1260,+ "flag_minnesota_timberwolves": 1262,+ "Flag_Mlwaukee_Bucks": 1261,+ "Flag_Moderator": 528,+ "flag_nba": 1263,+ "flag_neogaf": 616,+ "flag_neworleans_pelicans": 1264,+ "flag_newyork_knicks": 1265,+ "flag_nvidia": 808,+ "Flag_Oddworld_Necrum": 632,+ "Flag_Oddworld_RF": 633,+ "flag_oklahomacity_thunder": 1266,+ "Flag_Operation_Sports": 726,+ "flag_orlando_magic": 1267,+ "Flag_PanicButton": 829,+ "Flag_PCGamer": 667,+ "flag_philadelphia_76ers": 1268,+ "flag_phoenix_suns": 1269,+ "Flag_Pirate": 217,+ "flag_portland_trailblazers": 1270,+ "Flag_Rainbow": 490,+ "Flag_Razer": 573,+ "Flag_Reddit": 630,+ "flag_rl_garage": 645,+ "Flag_RocketBeans": 869,+ "flag_sacramento_kings": 1271,+ "flag_sanantonio_spurs": 1272,+ "Flag_Shacknews": 1213,+ "Flag_Shadowgate": 218,+ "Flag_SomethingAwful": 699,+ "Flag_StrikeVectorEX": 219,+ "Flag_Superman": 805,+ "Flag_TeamFat": 220,+ "flag_toronto_raptors": 1273,+ "Flag_Translator": 530,+ "Flag_Twitch": 221,+ "Flag_Unreal": 222,+ "Flag_Utah_Jazz": 1274,+ "flag_valve_ApLabs": 656,+ "Flag_Valve_Cake": 657,+ "Flag_VGX": 693,+ "Flag_Warframe": 223,+ "flag_washington_wizards": 1275,+ "Flag_WhiteFlag": 491,+ "Flag_WonderWoman": 806,+ "Flag_Worms": 1008,+ "Hat_AlphaHat": 224,+ "Hat_Antlers": 774,+ "Hat_BaseballCap_Back": 1328,+ "Hat_BaseballCap01": 1305,+ "Hat_Beanie": 225,+ "Hat_BeerHelmet": 493,+ "Hat_Beret": 775,+ "Hat_BikerHat": 776,+ "Hat_BirthdayCake": 789,+ "Hat_BoomBox": 521,+ "Hat_Boot": 740,+ "Hat_Bow": 811,+ "Hat_BPH": 227,+ "Hat_CaptainHat": 741,+ "Hat_CatEars": 810,+ "Hat_CatOLantern": 546,+ "Hat_Chainsaw": 795,+ "Hat_ChefsHat": 756,+ "Hat_Cockroach": 769,+ "Hat_CowboyHat": 1316,+ "Hat_CowSkull": 685,+ "Hat_Crown": 228,+ "hat_deadmau5": 796,+ "Hat_Deerstalker": 792,+ "Hat_DerbyHat": 790,+ "Hat_DetectiveHat": 742,+ "Hat_DevilHorns": 229,+ "HAT_DoughboyHelmet": 743,+ "Hat_DWI": 494,+ "Hat_Fez": 230,+ "Hat_Fireman": 231,+ "Hat_FlatHat": 1339,+ "HAT_FruitHat": 744,+ "hat_futureglasses": 1288,+ "HAT_GentlemanHat": 745,+ "Hat_GolfHat": 1326,+ "Hat_GraduationCap": 778,+ "Hat_Halo": 232,+ "Hat_Hardhat": 233,+ "Hat_LightBulb": 644,+ "Hat_Mariachi": 234,+ "Hat_Mohawk": 638,+ "Hat_Paper_Boat": 770,+ "Hat_Party": 812,+ "Hat_Pigeon": 817,+ "Hat_PirateHat": 235,+ "Hat_PizzaLight": 236,+ "Hat_Plunger": 772,+ "Hat_PoliceHat": 746,+ "Hat_PoliceSiren": 237,+ "Hat_PortalCake": 661,+ "Hat_Rasta": 771,+ "Hat_RatTrap": 782,+ "Hat_RegularChristmasTree": 639,+ "Hat_ReindeerAntlers": 640,+ "Hat_Rhino": 780,+ "Hat_SadChristmasTree": 641,+ "Hat_SantaHat": 642,+ "Hat_SharkFin": 579,+ "Hat_Shuriken": 773,+ "Hat_Sombrero": 238,+ "Hat_Taxi": 239,+ "Hat_Tiara": 495,+ "Hat_TopHat": 240,+ "Hat_TourneyWinner": 390,+ "HAT_TrafficCone": 747,+ "Hat_TrainConductor": 547,+ "Hat_Tricorn": 580,+ "Hat_TruckerHat": 1338,+ "Hat_Unihorn": 748,+ "Hat_Viking_Helmet": 241,+ "Hat_Visor": 1342,+ "Hat_WhiteHat": 1332,+ "Hat_Witch": 242,+ "Hat_WizardHat": 243,+ "Hat_Worms": 1028,+ "Logo_Barracudas": 244,+ "Logo_Blacklight": 245,+ "Logo_Bombers": 246,+ "Logo_Cyclones": 247,+ "Logo_Destroyers": 248,+ "Logo_Dragons": 249,+ "Logo_Express": 250,+ "Logo_Guardians": 251,+ "Logo_Knights": 252,+ "Logo_Kodiaks": 253,+ "Logo_Mammoths": 254,+ "Logo_Monarchs": 255,+ "Logo_Phantoms": 256,+ "Logo_Pharaohs": 257,+ "Logo_Pioneers": 258,+ "Logo_Ravagers": 259,+ "Logo_Rebels": 260,+ "Logo_Rovers": 261,+ "Logo_Scorpions": 262,+ "Logo_Skyhawks": 263,+ "Logo_Wolves": 264,+ "Pack_CommunityFlags": 496,+ "Pack_CountryFlags": 265,+ "pack_nba": 1277,+ "Pack_VideoGamesFlags": 543,+ "PaintFinish_BrushedMetal": 266,+ "PaintFinish_Camo": 541,+ "PaintFinish_Corroded": 268,+ "PaintFinish_Cracked": 542,+ "PaintFinish_Default": 270,+ "PaintFinish_GlossyCarbonFiber": 272,+ "PaintFinish_GreyCar": 623,+ "PaintFinish_Matte": 273,+ "PaintFinish_Metallic": 274,+ "PaintFinish_MetallicPearl": 275,+ "PaintFinish_Pearlescent": 276,+ "PaintFinish_Plastic": 277,+ "PaintFinish_ToonGlossy": 279,+ "PaintFinish_ToonGlossyWood": 280,+ "PaintFinish_ToonMatte": 281,+ "PaintFinish_Wood": 283,+ "Pennant_BlueChecker": 284,+ "Pennant_Camo": 285,+ "Pennant_OrangeNylon": 286,+ "Pennant_Psyonix": 287,+ "Skin_Aftershock_Aztec": 1306,+ "Skin_Aftershock_Gato": 1308,+ "Skin_Aftershock_Radioactive": 1311,+ "Skin_Aftershock_Shockwave": 1312,+ "Skin_Aftershock_Tiger": 1313,+ "Skin_Aftershock_Wings": 1314,+ "Skin_Backfire_Flames": 288,+ "Skin_Backfire_Lightning": 289,+ "Skin_Backfire_Skulls": 290,+ "Skin_Backfire_Stars": 291,+ "Skin_Backfire_Stripes": 292,+ "Skin_Backfire_Tech": 293,+ "Skin_Backfire_Wings": 294,+ "Skin_Force_Flames": 295,+ "Skin_Force_Junk": 1178,+ "Skin_Force_Lightning": 296,+ "Skin_Force_Skulls": 297,+ "Skin_Force_Stars": 298,+ "Skin_Force_Stripes": 299,+ "Skin_Force_Tech": 300,+ "Skin_Force_Wings": 301,+ "Skin_Import_Gato": 497,+ "Skin_Import_Nitrous": 498,+ "Skin_Import_Ohai": 499,+ "Skin_Import_Stripes": 501,+ "Skin_Import_Technologic": 502,+ "Skin_Import_Wisp": 503,+ "Skin_Interceptor_Flames": 669,+ "Skin_Interceptor_Getkraken": 700,+ "Skin_Interceptor_Kitsune": 670,+ "Skin_Interceptor_Sandgirl": 701,+ "Skin_Interceptor_Spikes": 671,+ "Skin_Interceptor_Tribal": 672,+ "skin_marauder_avalanche": 1345,+ "Skin_Marauder_BigBuck": 1340,+ "skin_marauder_gasmask": 1346,+ "skin_marauder_safari": 1348,+ "Skin_Marauder_Stripes": 1341,+ "skin_marauder_wings": 1352,+ "Skin_MuscleCar_Diammond": 1179,+ "Skin_MuscleCar_Flames": 504,+ "Skin_MuscleCar_Skorpion": 506,+ "Skin_MuscleCar_Skulls": 507,+ "Skin_MuscleCar_Stripes": 508,+ "Skin_MuscleCar_Tribal": 509,+ "Skin_MuscleCar_Wings": 510,+ "Skin_NeoBike_Cutter": 1320,+ "Skin_NeoBike_FormulaIII": 1321,+ "Skin_NeoBike_Kaiju": 1322,+ "Skin_NeoBike_MouseCat": 1323,+ "Skin_NeoBike_Neo": 1324,+ "Skin_NeoBike_Pegasus": 1325,+ "Skin_NeoCar_Flames": 1173,+ "Skin_NeoCar_Pill": 1279,+ "Skin_NeoCar_Squid": 1280,+ "Skin_NeoCar_Stars": 1174,+ "Skin_NeoCar_Stripes": 1175,+ "Skin_NeoCar_Track": 1176,+ "Skin_Octane_Flames": 302,+ "Skin_Octane_Lightning": 303,+ "Skin_Octane_Racer": 1065,+ "Skin_Octane_Skulls": 304,+ "Skin_Octane_Stars": 305,+ "Skin_Octane_Stripes": 306,+ "Skin_Octane_Tech": 307,+ "Skin_Octane_Wings": 308,+ "Skin_Orion_Flames": 309,+ "Skin_Orion_Lightning": 310,+ "Skin_Orion_Skulls": 311,+ "Skin_Orion_Stars": 312,+ "Skin_Orion_Stripes": 313,+ "Skin_Orion_Tech": 314,+ "Skin_Orion_Wings": 315,+ "Skin_Rhino_Flames": 316,+ "Skin_Rhino_Lightning": 317,+ "Skin_Rhino_Skulls": 318,+ "Skin_Rhino_Stars": 319,+ "Skin_Rhino_Stripes": 320,+ "Skin_Rhino_TechSplat": 321,+ "Skin_Rhino_Wings": 322,+ "Skin_Scarab_Clouds": 585,+ "Skin_Scarab_Flames": 591,+ "Skin_Scarab_Hearts": 586,+ "Skin_Scarab_RollerDerby": 592,+ "Skin_Scarab_Tiger": 587,+ "Skin_Scarab_Tribal": 588,+ "Skin_Spark_Flames": 323,+ "Skin_Spark_Lightning": 324,+ "Skin_Spark_Skulls": 325,+ "Skin_Spark_Stars": 326,+ "Skin_Spark_Stripes": 327,+ "Skin_Spark_Tech": 328,+ "Skin_Spark_Wings": 329,+ "Skin_Torch_Flames": 330,+ "Skin_Torch_Lightning": 331,+ "Skin_Torch_Skulls": 332,+ "Skin_Torch_Stars": 333,+ "Skin_Torch_Stripes": 334,+ "Skin_Torch_Tech": 335,+ "Skin_Torch_Wings": 336,+ "Skin_Torment_Flames": 337,+ "Skin_Torment_Lightning": 338,+ "Skin_Torment_Skulls": 339,+ "Skin_Torment_Stars": 340,+ "Skin_Torment_Stripes": 341,+ "Skin_Torment_Tech": 342,+ "Skin_Torment_Wings": 343,+ "Skin_Vanquish_Dots": 344,+ "Skin_Vanquish_Flames": 345,+ "Skin_Vanquish_Lightning": 346,+ "Skin_Vanquish_Skulls": 347,+ "Skin_Vanquish_Stars": 348,+ "Skin_Vanquish_Stripes": 349,+ "Skin_Vanquish_Wings": 350,+ "Skin_Venom_Dots": 351,+ "Skin_Venom_Flames": 352,+ "Skin_Venom_Flex": 1084,+ "Skin_Venom_Lightning": 353,+ "Skin_Venom_Skulls": 354,+ "Skin_Venom_Stripes": 355,+ "Skin_Venom_Tagged": 356,+ "Skin_Venom_Wings": 357,+ "Skin_WastelandTruck_Bomber": 674,+ "Skin_WastelandTruck_Bunny": 675,+ "Skin_WastelandTruck_Cyclops": 694,+ "Skin_WastelandTruck_Stripe": 687,+ "Skin_WastelandTruck_Tagged": 695,+ "Skin_WastelandTruck_Tribal": 696,+ "Skin_Zippy_Flames": 583,+ "Skin_Zippy_Hearts": 581,+ "Skin_Zippy_HeckTec": 589,+ "Skin_Zippy_Leopard": 584,+ "Skin_Zippy_MeanMachine": 590,+ "Skin_Zippy_Tiger": 582,+ "StreamerFlag_Ach_Hunter": 610,+ "StreamerFlag_AgryJoe": 548,+ "StreamerFlag_Annemunition": 531,+ "StreamerFlag_EatMyDiction": 532,+ "StreamerFlag_Funhaus": 611,+ "StreamerFlag_GassyMexican": 511,+ "StreamerFlag_ITMEJP": 533,+ "StreamerFlag_Lirik": 513,+ "StreamerFlag_Lol_Renaynay": 628,+ "StreamerFlag_Polaris": 608,+ "StreamerFlag_Rooster_Teeth": 612,+ "StreamerFlag_SaudiGamer": 534,+ "StreamerFlag_SeriousGaming": 572,+ "StreamerFlag_Spooky1611": 514,+ "StreamerFlag_Team_PowA": 515,+ "StreamerFlag_TheAttack": 535,+ "StreamerFlag_Youtube": 516,+ "TourneyFlag_ESL_Champ": 537,+ "TourneyFlag_ESL": 536,+ "TourneyFlag_MLG": 538,+ "TourneyFlag_TourneyChamp": 539,+ "WHEEL_Aftershock": 1315,+ "WHEEL_AlphaRim": 358,+ "WHEEL_Armadillo": 618,+ "WHEEL_Atlantis": 359,+ "WHEEL_Ballistic": 360,+ "WHEEL_Bling": 361,+ "WHEEL_Brink": 362,+ "WHEEL_Caliber": 363,+ "WHEEL_Carriage": 549,+ "WHEEL_Cog": 716,+ "WHEEL_Crypt": 364,+ "WHEEL_Darkcar": 874,+ "WHEEL_DeepDish": 365,+ "WHEEL_Dynamo": 366,+ "WHEEL_Forge": 367,+ "WHEEL_GreyCar": 609,+ "WHEEL_Hydra": 368,+ "WHEEL_LowRider": 369,+ "Wheel_Marauder": 1343,+ "WHEEL_Mob": 370,+ "WHEEL_Neo": 797,+ "WHEEL_NeoWheel": 1177,+ "Wheel_Ninja": 371,+ "WHEEL_OffRoad": 372,+ "Wheel_Pedigree": 373,+ "WHEEL_Revolution": 374,+ "WHEEL_Scarab": 540,+ "WHEEL_SingleSpoke": 518,+ "WHEEL_SkullxBones": 519,+ "WHEEL_SnowTire": 375,+ "Wheel_SoccerBall": 386,+ "WHEEL_Spiked": 690,+ "Wheel_Spinner": 388,+ "WHEEL_Star": 376,+ "WHEEL_Storm": 377,+ "WHEEL_SweetTooth": 378,+ "WHEEL_Tarantula": 379,+ "WHEEL_Triad": 380,+ "WHEEL_Vortex": 381,+ "Wheel_Vulcan": 382,+ "WHEEL_Warthog": 719,+ "Wheel_WastelandTruck": 613,+ "WHEEL_Wynd": 383+}
+ data/properties.json view
@@ -0,0 +1,128 @@+{+ "Engine.Actor:bBlockActors": "boolean",+ "Engine.Actor:bCollideActors": "boolean",+ "Engine.Actor:bCollideWorld": "boolean",+ "Engine.Actor:bHardAttach": "boolean",+ "Engine.Actor:bHidden": "boolean",+ "Engine.Actor:bNetOwner": "boolean",+ "Engine.Actor:bProjTarget": "boolean",+ "Engine.Actor:bTearOff": "boolean",+ "Engine.Actor:DrawScale": "float",+ "Engine.Actor:Owner": "flagged_int",+ "Engine.Actor:RelativeLocation": "location",+ "Engine.Actor:RelativeRotation": "relative_rotation",+ "Engine.Actor:ReplicatedCollisionType": "flagged_int",+ "Engine.Actor:Role": "enum",+ "Engine.GameReplicationInfo:bMatchIsOver": "boolean",+ "Engine.GameReplicationInfo:GameClass": "flagged_int",+ "Engine.GameReplicationInfo:ServerName": "string",+ "Engine.Pawn:bCanSwatTurn": "boolean",+ "Engine.Pawn:bRootMotionFromInterpCurve": "boolean",+ "Engine.Pawn:bSimulateGravity": "boolean",+ "Engine.Pawn:PlayerReplicationInfo": "flagged_int",+ "Engine.PlayerReplicationInfo:bAdmin": "boolean",+ "Engine.PlayerReplicationInfo:bBot": "boolean",+ "Engine.PlayerReplicationInfo:bFromPreviousLevel": "boolean",+ "Engine.PlayerReplicationInfo:bIsSpectator": "boolean",+ "Engine.PlayerReplicationInfo:bOnlySpectator": "boolean",+ "Engine.PlayerReplicationInfo:bOutOfLives": "boolean",+ "Engine.PlayerReplicationInfo:bReadyToPlay": "boolean",+ "Engine.PlayerReplicationInfo:bWaitingPlayer": "boolean",+ "Engine.PlayerReplicationInfo:Ping": "byte",+ "Engine.PlayerReplicationInfo:PlayerID": "int",+ "Engine.PlayerReplicationInfo:PlayerName": "string",+ "Engine.PlayerReplicationInfo:RemoteUserData": "string",+ "Engine.PlayerReplicationInfo:Score": "int",+ "Engine.PlayerReplicationInfo:Team": "flagged_int",+ "Engine.PlayerReplicationInfo:UniqueId": "unique_id",+ "Engine.TeamInfo:Score": "int",+ "Engine.TeamInfo:TeamIndex": "flagged_int",+ "ProjectX.GRI_X:bGameStarted": "boolean",+ "ProjectX.GRI_X:GameServerID": "qword",+ "ProjectX.GRI_X:ReplicatedGameMutatorIndex": "int",+ "ProjectX.GRI_X:ReplicatedGamePlaylist": "int",+ "ProjectX.GRI_X:Reservations": "reservation",+ "TAGame.Ball_TA:GameEvent": "flagged_int",+ "TAGame.Ball_TA:HitTeamNum": "byte",+ "TAGame.Ball_TA:ReplicatedAddedCarBounceScale": "float",+ "TAGame.Ball_TA:ReplicatedBallMaxLinearSpeedScale": "float",+ "TAGame.Ball_TA:ReplicatedBallScale": "float",+ "TAGame.Ball_TA:ReplicatedExplosionData": "explosion",+ "TAGame.Ball_TA:ReplicatedWorldBounceScale": "float",+ "TAGame.CameraSettingsActor_TA:bUsingBehindView": "boolean",+ "TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera": "boolean",+ "TAGame.CameraSettingsActor_TA:CameraPitch": "byte",+ "TAGame.CameraSettingsActor_TA:CameraYaw": "byte",+ "TAGame.CameraSettingsActor_TA:PRI": "flagged_int",+ "TAGame.CameraSettingsActor_TA:ProfileSettings": "cam_settings",+ "TAGame.Car_TA:ReplicatedDemolish": "demolish",+ "TAGame.Car_TA:TeamPaint": "team_paint",+ "TAGame.CarComponent_Boost_TA:bNoBoost": "boolean",+ "TAGame.CarComponent_Boost_TA:BoostModifier": "float",+ "TAGame.CarComponent_Boost_TA:bUnlimitedBoost": "boolean",+ "TAGame.CarComponent_Boost_TA:RechargeDelay": "float",+ "TAGame.CarComponent_Boost_TA:RechargeRate": "float",+ "TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount": "byte",+ "TAGame.CarComponent_Dodge_TA:DodgeTorque": "location",+ "TAGame.CarComponent_FlipCar_TA:bFlipRight": "boolean",+ "TAGame.CarComponent_FlipCar_TA:FlipCarTime": "float",+ "TAGame.CarComponent_TA:ReplicatedActive": "byte",+ "TAGame.CarComponent_TA:Vehicle": "flagged_int",+ "TAGame.CrowdActor_TA:GameEvent": "flagged_int",+ "TAGame.CrowdActor_TA:ModifiedNoise": "float",+ "TAGame.CrowdActor_TA:ReplicatedCountDownNumber": "int",+ "TAGame.CrowdActor_TA:ReplicatedOneShotSound": "flagged_int",+ "TAGame.CrowdManager_TA:GameEvent": "flagged_int",+ "TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound": "flagged_int",+ "TAGame.GameEvent_Soccar_TA:bBallHasBeenHit": "boolean",+ "TAGame.GameEvent_Soccar_TA:bOverTime": "boolean",+ "TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger": "music_stinger",+ "TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam": "byte",+ "TAGame.GameEvent_Soccar_TA:RoundNum": "int",+ "TAGame.GameEvent_Soccar_TA:SecondsRemaining": "int",+ "TAGame.GameEvent_SoccarPrivate_TA:MatchSettings": "private_match_settings",+ "TAGame.GameEvent_TA:bHasLeaveMatchPenalty": "boolean",+ "TAGame.GameEvent_TA:BotSkill": "int",+ "TAGame.GameEvent_TA:GameMode": "game_mode",+ "TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining": "int",+ "TAGame.GameEvent_TA:ReplicatedStateIndex": "byte",+ "TAGame.GameEvent_TA:ReplicatedStateName": "int",+ "TAGame.GameEvent_Team_TA:bDisableMutingOtherTeam": "boolean",+ "TAGame.GameEvent_Team_TA:MaxTeamSize": "int",+ "TAGame.GRI_TA:NewDedicatedServerIP": "string",+ "TAGame.PRI_TA:bIsInSplitScreen": "boolean",+ "TAGame.PRI_TA:bMatchMVP": "boolean",+ "TAGame.PRI_TA:bOnlineLoadoutSet": "boolean",+ "TAGame.PRI_TA:bReady": "boolean",+ "TAGame.PRI_TA:bUsingBehindView": "boolean",+ "TAGame.PRI_TA:bUsingFreecam": "boolean",+ "TAGame.PRI_TA:bUsingSecondaryCamera": "boolean",+ "TAGame.PRI_TA:bVoteToForfeitDisabled": "boolean",+ "TAGame.PRI_TA:CameraPitch": "byte",+ "TAGame.PRI_TA:CameraSettings": "cam_settings",+ "TAGame.PRI_TA:CameraYaw": "byte",+ "TAGame.PRI_TA:ClientLoadout": "loadout",+ "TAGame.PRI_TA:ClientLoadoutOnline": "loadout_online",+ "TAGame.PRI_TA:MatchAssists": "int",+ "TAGame.PRI_TA:MatchGoals": "int",+ "TAGame.PRI_TA:MatchSaves": "int",+ "TAGame.PRI_TA:MatchScore": "int",+ "TAGame.PRI_TA:MatchShots": "int",+ "TAGame.PRI_TA:PartyLeader": "party_leader",+ "TAGame.PRI_TA:PersistentCamera": "flagged_int",+ "TAGame.PRI_TA:ReplicatedGameEvent": "flagged_int",+ "TAGame.PRI_TA:Title": "int",+ "TAGame.PRI_TA:TotalXP": "int",+ "TAGame.RBActor_TA:bFrozen": "boolean",+ "TAGame.RBActor_TA:bReplayActor": "boolean",+ "TAGame.RBActor_TA:ReplicatedRBState": "rigid_body_state",+ "TAGame.Team_Soccar_TA:GameScore": "int",+ "TAGame.Team_TA:CustomTeamName": "string",+ "TAGame.Team_TA:GameEvent": "flagged_int",+ "TAGame.Team_TA:LogoData": "flagged_int",+ "TAGame.Vehicle_TA:bDriving": "boolean",+ "TAGame.Vehicle_TA:bReplicatedHandbrake": "boolean",+ "TAGame.Vehicle_TA:ReplicatedSteer": "byte",+ "TAGame.Vehicle_TA:ReplicatedThrottle": "byte",+ "TAGame.VehiclePickup_TA:ReplicatedPickupData": "pickup"+}
library/Octane/Data.hs view
@@ -1,27 +1,68 @@-module Octane.Data- ( module Octane.Data.Antennas- , module Octane.Data.Bodies- , module Octane.Data.Bots- , module Octane.Data.Classes- , module Octane.Data.Decals- , module Octane.Data.Finishes- , module Octane.Data.GameModes- , module Octane.Data.Logos- , module Octane.Data.Properties- , module Octane.Data.RocketTrails- , module Octane.Data.Toppers- , module Octane.Data.Wheels- ) where+{-# LANGUAGE TemplateHaskell #-} -import Octane.Data.Antennas-import Octane.Data.Bodies-import Octane.Data.Bots-import Octane.Data.Classes-import Octane.Data.Decals-import Octane.Data.Finishes-import Octane.Data.GameModes-import Octane.Data.Logos-import Octane.Data.Properties-import Octane.Data.RocketTrails-import Octane.Data.Toppers-import Octane.Data.Wheels+module Octane.Data where++import qualified Data.Bimap as Bimap+import qualified Data.FileEmbed as FileEmbed+import qualified Data.Map.Strict as Map+import qualified Data.Set as Set+import qualified Data.Text as StrictText+import qualified Octane.Utility.Embed as Embed++-- $setup+-- >>> :set -XOverloadedStrings+++-- | A map from object names to their class names.+--+-- >>> Map.lookup "Archetypes.Ball.Ball_Default" classes+-- Just "TAGame.Ball_TA"+--+-- Note that some object names have been normalized to make lookup easier.+--+-- >>> Map.lookup "Neotokyo_p.TheWorld:PersistentLevel.InMapScoreboard_TA_0@" classes+-- Nothing+-- >>> Map.lookup "TheWorld:PersistentLevel.InMapScoreboard_TA" classes+-- Just "TAGame.InMapScoreboard_TA"+classes :: Map.Map StrictText.Text StrictText.Text+classes = Embed.decodeMap $(FileEmbed.embedFile "data/classes.json")+++-- | A set of classes that have an initial location vector.+--+-- >>> Set.member "TAGame.Ball_TA" classesWithLocation+-- True+classesWithLocation :: Set.Set StrictText.Text+classesWithLocation = Embed.decodeSet $(FileEmbed.embedFile "data/classes-with-location.json")+++-- | A set of classes that have an initial rotation vector.+--+-- >>> Set.member "TAGame.Ball_TA" classesWithRotation+-- True+classesWithRotation :: Set.Set StrictText.Text+classesWithRotation = Embed.decodeSet $(FileEmbed.embedFile "data/classes-with-rotation.json")+++-- | A one-to-one mapping between game mode IDs and their names.+--+-- >>> Bimap.lookup 1 gameModes :: Maybe StrictText.Text+-- Just "Hockey"+gameModes :: Bimap.Bimap Int StrictText.Text+gameModes = Embed.decodeBimap $(FileEmbed.embedFile "data/game-modes.json")+++-- | A one-to-one mapping between product IDs and their names.+--+-- >>> Bimap.lookup 1 products :: Maybe StrictText.Text+-- Just "Antenna_8Ball"+products :: Bimap.Bimap Word StrictText.Text+products = Embed.decodeBimap $(FileEmbed.embedFile "data/products.json")+++-- | A mapping between property names and their serialized type.+--+-- >>> Map.lookup "Engine.Actor:bBlockActors" properties+-- Just "boolean"+properties :: Map.Map StrictText.Text StrictText.Text+properties = Embed.decodeMap $(FileEmbed.embedFile "data/properties.json")
− library/Octane/Data/Antennas.hs
@@ -1,435 +0,0 @@-module Octane.Data.Antennas (antennas) where--import Data.Function ((&))--import qualified Data.Bimap as Bimap-import qualified Data.Text as StrictText----- | A one-to-one mapping between antenna IDs and their names.-antennas :: Bimap.Bimap Int StrictText.Text-antennas =- [ ("None", 0)- , ("(Beta Reward) Gold Nugget", 6)- , ("8-Ball", 1)- , ("Alien", 753)- , ("Balloon Dog", 752)- , ("Batman", 804)- , ("Blue Chequered Flag", 284)- , ("Bomb Pole", 614)- , ("Calavera", 574) -- DOTDSkull- , ("Camo Flag", 285)- , ("Candle", 757)- , ("Candy Cane", 649)- , ("Chick Magnet", 392)- , ("Cupcake", 393)- , ("Dave's Bread", 391)- , ("deadmau5", 781) -- Mau5- , ("Disco Ball", 800)- , ("Disconnect", 394)- , ("Dollar Sign", 3)- , ("Donut", 395)- , ("Foam Finger", 398)- , ("Fuzzy Brute", 593) -- FurballFrakenstein- , ("Fuzzy Vamp", 595) -- FurballVampire- , ("Genie Lamp", 798)- , ("Gingerbread Man", 5)- , ("Heart", 7)- , ("Holiday Gift", 650) -- ChristmasGift- , ("Horseshoe", 8)- , ("Hula Girl", 762)- , ("Jolly Roger", 217) -- Pirate- , ("Lightning Bolt", 9)- , ("Moai", 522)- , ("Parrot", 750)- , ("Peace", 11)- , ("Piñata", 400)- , ("Planetoid", 12) -- Saturn- , ("Radioactive", 615) -- RadiationSymbol- , ("Rainbow", 490)- , ("Reddit Snoo", 629)- , ("Retro Ball - Urban", 575)- , ("Retro Ball - Utopia", 576)- , ("Retro Ball - Wasteland", 577)- , ("Rocket", 755)- , ("Rose", 785)- , ("Rubber Duckie", 779)- , ("Safety Flag", 286) -- OrangeNylon- , ("Skull", 13)- , ("Smiley", 14)- , ("Snowman", 15)- , ("Soccer Ball", 16)- , ("Star", 17)- , ("Sunflower", 786)- , ("Superman", 805)- , ("Sweet Tooth", 18)- , ("Tennis Ball", 19)- , ("The Game Awards - Statue", 655) -- VGA_Statue- , ("UFO", 20)- , ("Venus Flytrap", 788)- , ("Waffle", 401)- , ("White Flag", 491)- , ("Wonder Woman", 806)- -- TODO: What are these called in game?- , ("Community", 527)- , ("ESL_Champ", 537)- , ("Eyeball", 396)- , ("Moderator", 528)- , ("PanicButton", 829)- , ("Psyonix", 287)- , ("TourneyChamp", 539)- , ("Translator", 530)- ]- ++ communityFlags- ++ countryFlags- ++ videoGames- ++ nbaFlags- & map (\ (v, k) -> (k, StrictText.pack v)) & Bimap.fromList---communityFlags :: [(String, Int)]-communityFlags =- [ ("9GAG", 799)- , ("AbleGamers", 814)- , ("Achievement Hunter", 610)- , ("Angry Army", 548) -- AgryJoe- , ("Anne Munition", 531)- , ("Day[9]TV", 654)- , ("Destructoid", 724)- , ("EMD1", 532) -- EatMyDiction- , ("ESL", 536)- , ("Funhaus", 611)- , ("Gamespot", 725)- , ("Gassy Mexican", 511)- , ("Gfinity", 732)- , ("GoldGlove", 728)- , ("IGN", 802)- , ("itmeJP", 533)- , ("LIRIK", 513)- , ("lolRenaynay", 628)- , ("MLG", 538)- , ("NeoGAF", 616)- , ("NVIDIA", 808)- , ("Operation Sports", 726)- , ("PC Gamer", 667)- , ("Polaris", 608)- , ("Razer", 573)- , ("Reddit", 630)- , ("RL Garage", 645)- , ("Rocket Beans TV", 869)- , ("Rooster Teeth", 612)- , ("Saudi Gamer", 534)- , ("Serious Gaming", 572)- , ("Something Awful", 699)- , ("Spooky1611", 514)- , ("Team Fat", 220)- , ("Team PowA", 515)- , ("The Attack", 535)- , ("The Game Awards - Logo", 693) -- VGX- , ("Twitch", 221)- , ("YouTube Gaming", 516)- ]---countryFlags :: [(String, Int)]-countryFlags =- [ ("Afghanistan", 407)- , ("Albania", 408)- , ("Algeria", 124)- , ("American Samoa", 409)- , ("Andorra", 830)- , ("Angola", 410)- , ("Anguilla", 831)- , ("Antigua & Barbuda", 832)- , ("Argentina", 125)- , ("Armenia", 411)- , ("Aruba", 833)- , ("Australia", 126)- , ("Austria", 127)- , ("Azerbaijan", 412)- , ("Bahamas", 834)- , ("Bahrain", 550)- , ("Bangladesh", 413)- , ("Barbados", 835)- , ("Belarus", 414)- , ("Belgium", 128)- , ("Belize", 551)- , ("Benin", 415)- , ("Bermuda", 836)- , ("Bhutan", 552)- , ("Bolivia", 416)- , ("Bosnia and Herzegovina", 129)- , ("Botswana", 553)- , ("Brazil", 130)- , ("British Virgin Islands", 837)- , ("Bulgaria", 131)- , ("Burkina Faso", 417)- , ("Burma", 418)- , ("Burundi", 419)- , ("Cambodia", 420)- , ("Cameroon", 132)- , ("Canada", 133)- , ("Cape Verde Islands", 134)- , ("Cayman Islands", 838)- , ("Central African Republic", 540)- , ("Chad", 422)- , ("Chile", 135)- , ("China", 136)- , ("Chinese Taipei", 198)- , ("Colombia", 137)- , ("Comoros", 554)- , ("Congo", 138)- , ("Congo DR", 423)- , ("Cook Islands", 839)- , ("Costa Rica", 139)- , ("Croatia", 140)- , ("Cuba", 424)- , ("Curacao", 840)- , ("Cyprus", 141)- , ("Czech Republic", 142)- , ("Côte d'Ivoire", 165)- , ("Denmark", 143)- , ("Djibouti", 555)- , ("Dominica", 841)- , ("Dominican Republic", 425)- , ("East Timor", 556)- , ("Ecuador", 144)- , ("Egypt", 426)- , ("El Salvador", 145)- , ("England", 146)- , ("Equatorial Guinea", 147)- , ("Eritrea", 427)- , ("Estonia", 428)- , ("Ethiopia", 429)- , ("Falkland Islands", 842)- , ("Faroe Islands", 843)- , ("Fiji", 557)- , ("Finland", 148)- , ("France", 149)- , ("Gabon", 430)- , ("Gambia", 558)- , ("Georgia", 431)- , ("Germany", 150)- , ("Ghana", 151)- , ("Gibraltar", 844)- , ("Greece", 152)- , ("Grenada", 863)- , ("Guam", 432)- , ("Guatemala", 153)- , ("Guinea", 154)- , ("Guinea Bissau", 559)- , ("Guyana", 560)- , ("Haiti", 433)- , ("Honduras", 155)- , ("Hong Kong", 156)- , ("Hungary", 157)- , ("Iceland", 158)- , ("India", 159)- , ("Indonesia", 160)- , ("Iran", 161)- , ("Iraq", 434)- , ("Ireland", 162)- , ("Isle Of Man", 845)- , ("Israel", 163)- , ("Italy", 164)- , ("Jamaica", 166)- , ("Japan", 167)- , ("Jordan", 435)- , ("Kazakhstan", 436)- , ("Kenya", 168)- , ("Kiribati", 846)- , ("Kosovo", 561)- , ("Kuwait", 437)- , ("Kyrgyzstan", 438)- , ("Laos", 439)- , ("Latvia", 440)- , ("Lebanon", 441)- , ("Lesotho", 562)- , ("Liberia", 442)- , ("Libya", 443)- , ("Lithuania", 444)- , ("Luxembourg", 169)- , ("Macau", 563)- , ("Macedonia", 445)- , ("Madagascar", 446)- , ("Malawi", 447)- , ("Malaysia", 170)- , ("Maldives", 847)- , ("Mali", 448)- , ("Malta", 171)- , ("Marshall Islands", 848)- , ("Mauritania", 449)- , ("Mauritius", 564)- , ("Mexico", 172)- , ("Micronesia", 849)- , ("Moldova", 450)- , ("Mongolia", 451)- , ("Montenegro", 452)- , ("Montserrat", 864)- , ("Morocco", 453)- , ("Mozambique", 454)- , ("Namibia", 457)- , ("Nepal", 458)- , ("Netherlands", 173)- , ("New Caledonia", 850)- , ("New Zealand", 174)- , ("Nicaragua", 175)- , ("Nigeria", 176)- , ("North Korea", 460)- , ("North Mariana Islands", 456)- , ("Northern Ireland", 177)- , ("Norway", 178)- , ("Oman", 461)- , ("Palestine", 462)- , ("Palau", 851)- , ("Palestine", 462)- , ("Panama", 180)- , ("Papua New Guinea", 463)- , ("Paraguay", 464)- , ("Peru", 181)- , ("Philippines", 182)- , ("Poland", 183)- , ("Portugal", 184)- , ("Puerto Rico", 465)- , ("Puntland", 565)- , ("Qatar", 466)- , ("Republic of Niger", 459)- , ("Romania", 185)- , ("Russia", 186)- , ("Rwanda", 467)- , ("Réunion", 566)- , ("Saint Kitts & Nevis", 852)- , ("Saint Lucia", 853)- , ("Saint Vincent", 854)- , ("Samoa", 855)- , ("San Marino", 856)- , ("Sao Tome", 857)- , ("Saudi Arabia", 468)- , ("Scotland", 187)- , ("Senegal", 188)- , ("Serbia", 189)- , ("Seychelles", 858)- , ("Sierra Leone", 469)- , ("Singapore", 190)- , ("Slovakia", 191)- , ("Slovenia", 192)- , ("Solomon Islands", 567)- , ("Somalia", 470)- , ("Somaliland", 568)- , ("South Africa", 193)- , ("South Korea", 194)- , ("South Sudan", 471)- , ("Spain", 195)- , ("Sri Lanka", 389)- , ("Sudan", 472)- , ("Suriname", 569)- , ("Swaziland", 570)- , ("Sweden", 196)- , ("Switzerland", 197)- , ("Syria", 473)- , ("Tahiti", 859)- , ("Tajikistan", 474)- , ("Tanzania", 475)- , ("Thailand", 199)- , ("Togo", 476)- , ("Tonga", 730)- , ("Trinidad and Tobago", 477)- , ("Tunisia", 200)- , ("Turkey", 201)- , ("Turkmenistan", 478)- , ("Turks & Caicos", 860)- , ("Uganda", 479)- , ("Ukraine", 204)- , ("United Arab Emirates", 202)- , ("United Kingdom", 203)- , ("United States", 206)- , ("Uruguay", 502)- , ("US Virgin Islands", 480)- , ("Uzbekistan", 481)- , ("Vanuatu", 861)- , ("Vatican City", 862)- , ("Venezuela", 207)- , ("Vietnam", 208)- , ("Wales", 209)- , ("Western Sahara", 571)- , ("Yemen", 210)- , ("Zambia", 482)- , ("Zimbabwe", 483)- ]---nbaFlags :: [(String, Int)]-nbaFlags =- [ ("NBA", 1263)- , ("Atlanta Hawks", 1245)- , ("Boston Celtics", 1246)- , ("Brooklyn Nets", 1247)- , ("Charlotte Hornets", 1248)- , ("Chicago Bulls", 1249)- , ("Cleveland Cavaliers", 1250)- , ("Dallas Mavericks", 1251)- , ("Denver Nuggets", 1252)- , ("Detroit Pistons", 1253)- , ("Golden State Warriors", 1254)- , ("Houston Rockets", 1255)- , ("Indian Pacers", 1256)- , ("Los Angeles Clippers", 1257)- , ("Los Angeles Lakers", 1258)- , ("Memphis Grizzlies", 1259)- , ("Miami Heat", 1260)- , ("Milwaukee Bucks", 1261)- , ("Minnesota Timberwolves", 1262)- , ("New Orleans Pelicans", 1264)- , ("New Tork Knicks", 1265)- , ("Oklahoma City Thunder", 1266)- , ("Orlando Magic", 1267)- , ("Philadelphia 76ers", 1268)- , ("Phoenix Suns", 1269)- , ("Portland Trail Blazers", 1270)- , ("Sacramento Kings", 1271)- , ("San Antonio Spurs", 1272)- , ("Toronto Raptors", 1273)- , ("Utah Jazz", 1274)- , ("Washington Wizards", 1275)- ]---videoGames :: [(String, Int)]-videoGames =- [ ("Blacklight", 385)- , ("Blacklight: Retribution", 211)- , ("Chivalry - Agatha Knights", 525)- , ("Chivalry - Mason Order", 526)- , ("Edge Of Space", 213)- , ("Euro Truck Simulator Rig", 813) -- ETS2- , ("Fallout - Vault Boy", 673)- , ("Fenix Rage", 216)- , ("Goat Simulator - G2", 927)- , ("Goat Simulator - Goatenna", 867)- , ("Oddworld - Abe", 678)- , ("Oddworld - Molluck", 679)- , ("Oddworld - Necrum", 632)- , ("Oddworld - RuptureFarms", 633)- , ("Portal - Aperture Laboratories", 656)- , ("Portal - Cake Sticker", 657)- , ("Portal - Companion Cube", 681)- , ("Portal - PotatOS", 698)- , ("Portal - Wheatley", 686) -- Portal_PC- , ("Shadowgate", 218)- , ("Strike Vector EX", 219)- , ("Unreal", 222)- , ("Unreal Frag Center", 485)- , ("Unreal Tournament", 489) -- UTBlue- , ("Unreal Tournament (Classic)", 487) -- UT- , ("Unreal Tournament - Blue", 484) -- Epic_BlueFlag- , ("Unreal Tournament - Flak Shell", 397)- , ("Unreal Tournament - Red", 486) -- Epic_RedFlag- , ("Unreal Tournament 2004", 488)- , ("Warframe", 223)- , ("Warframe - Chroma", 682)- , ("Warframe - Excalibur", 684)- , ("Warframe - Loki", 683)- , ("Witcher Medallion", 749)- , ("Worms W.M.D", 1008)- , ("Worms W.M.D. Grenade", 1000)- ]
− library/Octane/Data/Bodies.hs
@@ -1,33 +0,0 @@-module Octane.Data.Bodies (bodies) where--import Data.Function ((&))--import qualified Data.Bimap as Bimap-import qualified Data.Text as StrictText----- | A one-to-one mapping between body IDs and their names.-bodies :: Bimap.Bimap Int StrictText.Text-bodies =- [ ("Armadillo", 625) -- GearsCar- , ("Backfire", 21)- , ("Batmobile", 803) -- Darkcar- , ("Breakout", 22) -- Force- , ("DeLorean Time Machine", 597) -- GreyCar- , ("Dominus", 403) -- MuscleCar- , ("Gizmo", 26) -- Spark- , ("Grog", 607) -- WastelandTruck- , ("Hogsticker", 723) -- Warthog- , ("Hotshot", 29) -- Torment- , ("Merc", 30) -- Vanquish- , ("Octane", 23)- , ("Paladin", 24) -- Orion- , ("Ripper", 600) -- Interceptor- , ("Road Hog", 25) -- Rhino- , ("Scarab", 404)- , ("Sweet Tooth", 27)- , ("Takumi", 402) -- Import- , ("Venom", 31)- , ("X-Devil", 28) -- Torch- , ("Zippy", 523)- ] & map (\ (v, k) -> (k, StrictText.pack v)) & Bimap.fromList
− library/Octane/Data/Bots.hs
@@ -1,66 +0,0 @@-module Octane.Data.Bots (bots) where--import Data.Function ((&))--import qualified Data.Bimap as Bimap-import qualified Data.Text as StrictText----- | A one-to-one mapping between bot IDs and their names.-bots :: Bimap.Bimap Int StrictText.Text-bots =- [ ("Astro", 70)- , ("Bane", 71)- , ("Beast", 72)- , ("Blade", 73)- , ("C-Block", 74)- , ("Captain", 75)- , ("Caveman", 76)- , ("Cougar", 77)- , ("Devil", 78)- , ("Diesel", 79)- , ("Dotty", 80)- , ("Dude", 81)- , ("Duke", 82)- , ("Dynamite", 83)- , ("Flame", 84)- , ("Flash", 85)- , ("Fossil", 86)- , ("Fury", 87)- , ("Hawk", 88)- , ("Hunter", 89)- , ("Imp", 90)- , ("Jet", 91)- , ("JM", 92)- , ("Kidd", 93)- , ("Laser", 94)- , ("Lightning", 95)- , ("Lucky", 96)- , ("Middy", 97)- , ("Mountain", 98)- , ("Nitro", 99)- , ("Outlaw", 100)- , ("Phoenix", 101)- , ("Raja", 102)- , ("Razor", 103)- , ("Retro", 104)- , ("Roundhouse", 105)- , ("Sabre", 106)- , ("Samson", 107)- , ("Savage", 108)- , ("Shadow", 109)- , ("Shield", 110)- , ("Siren", 111)- , ("Sky", 112)- , ("Squall", 113)- , ("Tank", 114)- , ("Thunder", 115)- , ("Titan", 116)- , ("Turbo", 117)- , ("Tusk", 118)- , ("Viper", 119)- , ("Warrior", 120)- , ("Wolf", 121)- , ("Yuri", 122)- , ("Zap", 123)- ] & map (\ (v, k) -> (k, StrictText.pack v)) & Bimap.fromList
− library/Octane/Data/Classes.hs
@@ -1,179 +0,0 @@-module Octane.Data.Classes- ( objectToClass- , locationClasses- , rotationClasses- ) where--import Data.Function ((&))-import Data.Monoid ((<>))--import qualified Data.Map.Strict as Map-import qualified Data.Set as Set-import qualified Data.Text as StrictText----- | A map from object names to their class names. Note that any trailing--- numbers have been stripped from the object names. So--- @Archetypes.Teams.Team0@ is in this map as @Archetypes.Teams.Team@.-objectToClass :: Map.Map StrictText.Text StrictText.Text-objectToClass = Map.foldrWithKey- (\ klass objects m -> objects- & Set.map (\ object -> (object, klass))- & Set.toList- & Map.fromList- & Map.union m)- Map.empty- classToObjects----- | A set of classes that have an initial location vector.-locationClasses :: Set.Set StrictText.Text-locationClasses =- [ "TAGame.Ball_TA"- , "TAGame.CameraSettingsActor_TA"- , "TAGame.CarComponent_Boost_TA"- , "TAGame.CarComponent_Dodge_TA"- , "TAGame.CarComponent_DoubleJump_TA"- , "TAGame.CarComponent_FlipCar_TA"- , "TAGame.CarComponent_Jump_TA"- , "TAGame.Car_Season_TA"- , "TAGame.Car_TA"- , "TAGame.GRI_TA"- , "TAGame.GameEvent_Season_TA"- , "TAGame.GameEvent_SoccarPrivate_TA"- , "TAGame.GameEvent_SoccarSplitscreen_TA"- , "TAGame.GameEvent_Soccar_TA"- , "TAGame.PRI_TA"- , "TAGame.Team_Soccar_TA"- ] & map StrictText.pack & Set.fromList----- | A set of classes that have an initial rotation vector.-rotationClasses :: Set.Set StrictText.Text-rotationClasses =- [ "TAGame.Ball_TA"- , "TAGame.Car_Season_TA"- , "TAGame.Car_TA"- ] & map StrictText.pack & Set.fromList---classToObjects :: Map.Map StrictText.Text (Set.Set StrictText.Text)-classToObjects = let- normal =- [ ( "TAGame.Ball_TA",- [ "Archetypes.Ball.Ball_Default"- , "Archetypes.Ball.Ball_Basketball"- , "Archetypes.Ball.Ball_Puck"- , "Archetypes.Ball.CubeBall"- ])- , ( "TAGame.CameraSettingsActor_TA",- [ "TAGame.CameraSettingsActor_TA:PRI"- , "TAGame.Default__CameraSettingsActor_TA"- ])- , ( "TAGame.CarComponent_Boost_TA",- [ "Archetypes.CarComponents.CarComponent_Boost"- ])- , ( "TAGame.CarComponent_Dodge_TA",- [ "Archetypes.CarComponents.CarComponent_Dodge"- ])- , ( "TAGame.CarComponent_DoubleJump_TA",- [ "Archetypes.CarComponents.CarComponent_DoubleJump"- ])- , ( "TAGame.CarComponent_FlipCar_TA",- [ "Archetypes.CarComponents.CarComponent_FlipCar"- ])- , ( "TAGame.CarComponent_Jump_TA",- [ "Archetypes.CarComponents.CarComponent_Jump"- ])- , ( "TAGame.Car_TA",- [ "Archetypes.Car.Car_Default"- , "Archetypes.GameEvent.GameEvent_Season:CarArchetype"- ])- , ( "TAGame.GameEvent_Season_TA",- [ "Archetypes.GameEvent.GameEvent_Season"- ])- , ( "TAGame.GameEvent_SoccarPrivate_TA",- [ "Archetypes.GameEvent.GameEvent_BasketballPrivate"- , "Archetypes.GameEvent.GameEvent_HockeyPrivate"- , "Archetypes.GameEvent.GameEvent_SoccarPrivate"- ])- , ( "TAGame.GameEvent_SoccarSplitscreen_TA",- [ "Archetypes.GameEvent.GameEvent_BasketballSplitscreen"- , "Archetypes.GameEvent.GameEvent_HockeySplitscreen"- , "Archetypes.GameEvent.GameEvent_SoccarSplitscreen"- ])- , ( "TAGame.GameEvent_Soccar_TA",- [ "Archetypes.GameEvent.GameEvent_Soccar"- , "Archetypes.GameEvent.GameEvent_Basketball"- ])- , ( "TAGame.GRI_TA",- [ "GameInfo_Basketball.GameInfo.GameInfo_Basketball:GameReplicationInfoArchetype"- , "Gameinfo_Hockey.GameInfo.Gameinfo_Hockey:GameReplicationInfoArchetype"- , "GameInfo_Season.GameInfo.GameInfo_Season:GameReplicationInfoArchetype"- , "GameInfo_Soccar.GameInfo.GameInfo_Soccar:GameReplicationInfoArchetype"- ])- , ( "TAGame.PRI_TA",- [ "TAGame.Default__PRI_TA"- ])- , ( "TAGame.Team_Soccar_TA",- [ "Archetypes.Teams.Team"- ])- , ( "TAGame.VoteActor_TA",- [ "TAGame.Default__VoteActor_TA"- ])- ] & map (\ (klass, objects) ->- ( StrictText.pack klass- , objects & map StrictText.pack & Set.fromList- ))- special =- [ ("TAGame.CrowdActor_TA", ".TheWorld:PersistentLevel.CrowdActor_TA_")- , ("TAGame.CrowdManager_TA", ".TheWorld:PersistentLevel.CrowdManager_TA_")- , ("TAGame.InMapScoreboard_TA", ".TheWorld:PersistentLevel.InMapScoreboard_TA_")- , ("TAGame.VehiclePickup_Boost_TA", ".TheWorld:PersistentLevel.VehiclePickup_Boost_TA_")- ] & map (\ (klass, suffix) ->- ( StrictText.pack klass- , levels & Set.map (\ level -> level <> StrictText.pack suffix)- ))- in Map.fromList (normal ++ special)---levels :: Set.Set StrictText.Text-levels =- [ "EuroStadium_Rainy_P"- , "HoopsStadium_P"- , "Neotokyo_p"- , "Park_Night_P"- , "Park_Rainy_P"- , "Stadium_p"- , "TrainStation_Night_P"- , "TrainStation_P"- , "Trainstation_Night_P"- , "UtopiaStadium_Dusk_P"- , "UtopiaStadium_Dusk_p"- , "UtopiaStadium_P"- , "Utopiastadium_p"- , "Wasteland_P"- , "Wasteland_p"- , "eurostad_oob_audio_map"- , "eurostadium_p"- , "eurostadium_rainy_audio"- , "hoopsstadium_sfx"- , "labs_circlepillars_p"- , "labs_cosmic_p"- , "labs_doublegoal_p"- , "labs_sfx"- , "labs_underpass_p"- , "labs_utopia_p"- , "neotokyo_sfx"- , "park_night_sfx"- , "park_p"- , "park_rainy_sfx"- , "park_sfx"- , "stadium_oob_audio_map"- , "stadium_p"- , "stadium_winter_p"- , "trainstation_p"- , "utopiastadium_p"- , "utopiastadium_sfx"- , "wasteland_sfx"- ] & map StrictText.pack & Set.fromList
− library/Octane/Data/Decals.hs
@@ -1,220 +0,0 @@-module Octane.Data.Decals (decals) where--import Data.Function ((&))--import qualified Data.Bimap as Bimap-import qualified Data.Text as StrictText----- | A one-to-one mapping between decal IDs and their names.-decals :: Bimap.Bimap Int StrictText.Text-decals =- [ ("Backfire", backfireDecals)- , ("Breakout", breakoutDecals)- , ("Dominus", dominusDecals)- , ("Gizmo", gizmoDecals)- , ("Grog", grogDecals)- , ("Hotshot", hotshotDecals)- , ("Merc", mercDecals)- , ("Octane", octaneDecals)- , ("Paladin", paladinDecals)- , ("Ripper", ripperDecals)- , ("Road Hog", roadHogDecals)- , ("Scarab", scarabDecals)- , ("Takumi", takumiDecals)- , ("Venom", venomDecals)- , ("X-Devil", xDevilDecals)- , ("Zippy", zippyDecals)- ]- & map (\ (body, values) -> values &- map (\ (v, k) -> (k, v ++ " [" ++ body ++ "]")))- & concat- & map (\ (k, v) -> (k, StrictText.pack v))- & Bimap.fromList- & Bimap.insert 0 (StrictText.pack "None")---backfireDecals :: [(String, Int)]-backfireDecals =- [ ("Flames", 288)- , ("Lightning", 289)- , ("Skulls", 290)- , ("Stars", 291)- , ("Stripes", 292)- , ("Tech", 293)- , ("Wings", 294)- ]---breakoutDecals :: [(String, Int)]-breakoutDecals =- [ ("Flames", 295)- , ("Lightning", 296)- , ("Skulls", 297)- , ("Stars", 298)- , ("Stripes", 299)- , ("Tech", 300)- , ("Wings", 301)- ]---dominusDecals :: [(String, Int)]-dominusDecals =- [ ("Flames", 504)- , ("Scorpions", 506) -- Skorpion- , ("Skulls", 507)- , ("Stripes", 508)- , ("Tats", 509) -- Tribal- , ("Wings", 510)- ]---gizmoDecals :: [(String, Int)]-gizmoDecals =- [ ("Flames", 323)- , ("Lightning", 324)- , ("Skulls", 325)- , ("Stars", 326)- , ("Stripes", 327)- , ("Tech", 328)- , ("Wings", 329)- ]---grogDecals :: [(String, Int)]-grogDecals =- [ ("Bomber", 674)- , ("Cyclops", 694)- , ("Lepus", 675) -- Bunny- , ("Stripes", 687)- , ("Tagged", 695)- , ("Tribal", 696)- ]---hotshotDecals :: [(String, Int)]-hotshotDecals =- [ ("Flames", 337)- , ("Lightning", 338)- , ("Skulls", 339)- , ("Stars", 340)- , ("Stripes", 341)- , ("Tech", 342)- , ("Wings", 343)- ]---mercDecals :: [(String, Int)]-mercDecals =- [ ("Dots", 344)- , ("Flames", 345)- , ("Lightning", 346)- , ("Skulls", 347)- , ("Stars", 348)- , ("Stripes", 349)- , ("Wings", 350)- ]---octaneDecals :: [(String, Int)]-octaneDecals =- [ ("Flames", 302)- , ("Lightning", 303)- , ("Skulls", 304)- , ("Stars", 305)- , ("Stripes", 306)- , ("Tech", 307)- , ("Wings", 308)- ]---paladinDecals :: [(String, Int)]-paladinDecals =- [ ("Flames", 309)- , ("Lightning", 310)- , ("Skulls", 311)- , ("Stars", 312)- , ("Stripes", 313)- , ("Tech", 314)- , ("Wings", 315)- ]---ripperDecals :: [(String, Int)]-ripperDecals =- [ ("Bomber", 701) -- Sandgirl- , ("Flames", 669)- , ("Ockie", 700) -- Getkraken- , ("Shot Fox", 670) -- Kitsune- , ("Spikes", 671)- , ("Tribal", 672)- ]---roadHogDecals :: [(String, Int)]-roadHogDecals =- [ ("Flames", 316)- , ("Lightning", 317)- , ("Skulls", 318)- , ("Stars", 319)- , ("Stripes", 320)- , ("Tech", 321) -- TechSplat- , ("Wings", 322)- ]---scarabDecals :: [(String, Int)]-scarabDecals =- [ ("Bomani", 585) -- Clouds- , ("Derby Girl", 592) -- RollerDerby- , ("Flames", 591)- , ("Hearts", 586)- , ("Tiger", 587)- , ("Tribal", 588)- ]---takumiDecals :: [(String, Int)]-takumiDecals =- [ ("Chaser", 503) -- Wisp- , ("Copycat", 497) -- Gato- , ("Crazy-8", 502) -- Technologic- , ("Gaki", 499) -- Ohai- , ("Reiko", 498) -- Nitrous- , ("Stripes", 501)- ]---venomDecals :: [(String, Int)]-venomDecals =- [ ("Dots", 351)- , ("Flames", 352)- , ("Lightning", 353)- , ("Skulls", 354)- , ("Stripes", 355)- , ("Tagged", 356)- , ("Wings", 357)- ]---xDevilDecals :: [(String, Int)]-xDevilDecals =- [ ("Flames", 330)- , ("Lightning", 331)- , ("Skulls", 332)- , ("Stars", 333)- , ("Stripes", 334)- , ("Tech", 335)- , ("Wings", 336)- ]---zippyDecals :: [(String, Int)]-zippyDecals =- [ ("Caboodle", 589) -- HeckTec- , ("Callous", 590) -- MeanMachine- , ("Flames", 583)- , ("Hearts", 581)- , ("Leopard", 584)- , ("Tiger", 582)- ]
− library/Octane/Data/Finishes.hs
@@ -1,28 +0,0 @@-module Octane.Data.Finishes (finishes) where--import Data.Function ((&))--import qualified Data.Bimap as Bimap-import qualified Data.Text as StrictText----- | A one-to-one mapping between paint finish IDs and their names.-finishes :: Bimap.Bimap Int StrictText.Text-finishes =- [ ("Brushed Metal", 266)- , ("Camo", 541)- , ("Carbon Fiber", 272) -- GlossyCarbonFiber- , ("Corroded Metal", 268) -- Corroded- , ("DeLorean Time Machine", 623) -- GreyCar- , ("Glossy", 270) -- Default- , ("Matte", 273)- , ("Metallic", 274)- , ("Metallic Pearl", 275)- , ("Pearlescent", 276)- , ("Semigloss", 277) -- Plastic- , ("Sun-Damaged", 542) -- Cracked- , ("Toon Glossy", 279)- , ("Toon Matte", 281)- , ("Toon Wood", 280)- , ("Wood", 283)- ] & map (\ (v, k) -> (k, StrictText.pack v)) & Bimap.fromList
− library/Octane/Data/GameModes.hs
@@ -1,15 +0,0 @@-module Octane.Data.GameModes (gameModes) where--import Data.Function ((&))--import qualified Data.Bimap as Bimap-import qualified Data.Text as StrictText----- | A one-to-one mapping between game mode IDs and their names.-gameModes :: Bimap.Bimap Int StrictText.Text-gameModes =- [ ("Soccar", 0)- , ("Hockey", 1)- , ("Hoops", 2)- ] & map (\ (v, k) -> (k, StrictText.pack v)) & Bimap.fromList
− library/Octane/Data/Logos.hs
@@ -1,33 +0,0 @@-module Octane.Data.Logos (logos) where--import Data.Function ((&))--import qualified Data.Bimap as Bimap-import qualified Data.Text as StrictText----- | A one-to-one mapping between logo IDs and their names.-logos :: Bimap.Bimap Int StrictText.Text-logos =- [ ("Barracudas", 244)- , ("Blacklight", 245)- , ("Bombers", 246)- , ("Cyclones", 247)- , ("Destroyers", 248)- , ("Dragons", 249)- , ("Express", 250)- , ("Guardians", 251)- , ("Knights", 252)- , ("Kodiaks", 253)- , ("Mammoths", 254)- , ("Monarchs", 255)- , ("Phantoms", 256)- , ("Pharaohs", 257)- , ("Pioneers", 258)- , ("Ravagers", 259)- , ("Rebels", 260)- , ("Rovers", 261)- , ("Scorpions", 262)- , ("Skyhawks", 263)- , ("Wolves", 264)- ] & map (\ (v, k) -> (k, StrictText.pack v)) & Bimap.fromList
− library/Octane/Data/Properties.hs
@@ -1,294 +0,0 @@-module Octane.Data.Properties- ( booleanProperties- , byteProperties- , camSettingsProperties- , demolishProperties- , enumProperties- , explosionProperties- , flaggedIntProperties- , floatProperties- , gameModeProperties- , intProperties- , loadoutOnlineProperties- , loadoutProperties- , locationProperties- , musicStingerProperties- , pickupProperties- , privateMatchSettingsProperties- , qWordProperties- , relativeRotationProperties- , reservationProperties- , rigidBodyStateProperties- , stringProperties- , teamPaintProperties- , uniqueIdProperties- ) where--import Data.Function ((&))--import qualified Data.Set as Set-import qualified Data.Text as StrictText----- | A set of properties that are booleans.-booleanProperties :: Set.Set StrictText.Text-booleanProperties =- [ "Engine.Actor:bBlockActors"- , "Engine.Actor:bCollideActors"- , "Engine.Actor:bCollideWorld"- , "Engine.Actor:bHardAttach"- , "Engine.Actor:bHidden"- , "Engine.Actor:bNetOwner"- , "Engine.Actor:bProjTarget"- , "Engine.Actor:bTearOff"- , "Engine.GameReplicationInfo:bMatchIsOver"- , "Engine.Pawn:bCanSwatTurn"- , "Engine.Pawn:bRootMotionFromInterpCurve"- , "Engine.Pawn:bSimulateGravity"- , "Engine.PlayerReplicationInfo:bAdmin"- , "Engine.PlayerReplicationInfo:bBot"- , "Engine.PlayerReplicationInfo:bFromPreviousLevel"- , "Engine.PlayerReplicationInfo:bIsSpectator"- , "Engine.PlayerReplicationInfo:bOnlySpectator"- , "Engine.PlayerReplicationInfo:bOutOfLives"- , "Engine.PlayerReplicationInfo:bReadyToPlay"- , "Engine.PlayerReplicationInfo:bWaitingPlayer"- , "ProjectX.GRI_X:bGameStarted"- , "TAGame.CameraSettingsActor_TA:bUsingBehindView"- , "TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera"- , "TAGame.CarComponent_Boost_TA:bNoBoost"- , "TAGame.CarComponent_Boost_TA:bUnlimitedBoost"- , "TAGame.CarComponent_FlipCar_TA:bFlipRight"- , "TAGame.GameEvent_Soccar_TA:bBallHasBeenHit"- , "TAGame.GameEvent_Soccar_TA:bOverTime"- , "TAGame.GameEvent_TA:bHasLeaveMatchPenalty"- , "TAGame.GameEvent_Team_TA:bDisableMutingOtherTeam"- , "TAGame.PRI_TA:bIsInSplitScreen"- , "TAGame.PRI_TA:bMatchMVP"- , "TAGame.PRI_TA:bOnlineLoadoutSet"- , "TAGame.PRI_TA:bReady"- , "TAGame.PRI_TA:bUsingBehindView"- , "TAGame.PRI_TA:bUsingFreecam"- , "TAGame.PRI_TA:bUsingSecondaryCamera"- , "TAGame.PRI_TA:bVoteToForfeitDisabled"- , "TAGame.RBActor_TA:bFrozen"- , "TAGame.RBActor_TA:bReplayActor"- , "TAGame.Vehicle_TA:bDriving"- , "TAGame.Vehicle_TA:bReplicatedHandbrake"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are bytes.-byteProperties :: Set.Set StrictText.Text-byteProperties =- [ "Engine.PlayerReplicationInfo:Ping"- , "TAGame.Ball_TA:HitTeamNum"- , "TAGame.CameraSettingsActor_TA:CameraPitch"- , "TAGame.CameraSettingsActor_TA:CameraYaw"- , "TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount"- , "TAGame.CarComponent_TA:ReplicatedActive"- , "TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam"- , "TAGame.GameEvent_TA:ReplicatedStateIndex"- , "TAGame.PRI_TA:CameraPitch"- , "TAGame.PRI_TA:CameraYaw"- , "TAGame.Vehicle_TA:ReplicatedSteer"- , "TAGame.Vehicle_TA:ReplicatedThrottle"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are camera settings.-camSettingsProperties :: Set.Set StrictText.Text-camSettingsProperties =- [ "TAGame.CameraSettingsActor_TA:ProfileSettings"- , "TAGame.PRI_TA:CameraSettings"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are demolitions.-demolishProperties :: Set.Set StrictText.Text-demolishProperties =- [ "TAGame.Car_TA:ReplicatedDemolish"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are enumerations.-enumProperties :: Set.Set StrictText.Text-enumProperties =- [ "Engine.Actor:Role"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are explosions.-explosionProperties :: Set.Set StrictText.Text-explosionProperties =- [ "TAGame.Ball_TA:ReplicatedExplosionData"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are flagged integers.-flaggedIntProperties :: Set.Set StrictText.Text-flaggedIntProperties =- [ "Engine.Actor:Owner"- , "Engine.Actor:ReplicatedCollisionType"- , "Engine.GameReplicationInfo:GameClass"- , "Engine.Pawn:PlayerReplicationInfo"- , "Engine.PlayerReplicationInfo:Team"- , "Engine.TeamInfo:TeamIndex"- , "TAGame.Ball_TA:GameEvent"- , "TAGame.CameraSettingsActor_TA:PRI"- , "TAGame.CarComponent_TA:Vehicle"- , "TAGame.CrowdActor_TA:GameEvent"- , "TAGame.CrowdActor_TA:ReplicatedOneShotSound"- , "TAGame.CrowdManager_TA:GameEvent"- , "TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound"- , "TAGame.PRI_TA:PersistentCamera"- , "TAGame.PRI_TA:ReplicatedGameEvent"- , "TAGame.Team_TA:GameEvent"- , "TAGame.Team_TA:LogoData"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are floats.-floatProperties :: Set.Set StrictText.Text-floatProperties =- [ "Engine.Actor:DrawScale"- , "TAGame.Ball_TA:ReplicatedAddedCarBounceScale"- , "TAGame.Ball_TA:ReplicatedBallMaxLinearSpeedScale"- , "TAGame.Ball_TA:ReplicatedBallScale"- , "TAGame.Ball_TA:ReplicatedWorldBounceScale"- , "TAGame.CarComponent_Boost_TA:BoostModifier"- , "TAGame.CarComponent_Boost_TA:RechargeDelay"- , "TAGame.CarComponent_Boost_TA:RechargeRate"- , "TAGame.CarComponent_FlipCar_TA:FlipCarTime"- , "TAGame.CrowdActor_TA:ModifiedNoise"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are game modes.-gameModeProperties :: Set.Set StrictText.Text-gameModeProperties =- [ "TAGame.GameEvent_TA:GameMode"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are integers.-intProperties :: Set.Set StrictText.Text-intProperties =- [ "Engine.PlayerReplicationInfo:PlayerID"- , "Engine.PlayerReplicationInfo:Score"- , "Engine.TeamInfo:Score"- , "ProjectX.GRI_X:ReplicatedGameMutatorIndex"- , "ProjectX.GRI_X:ReplicatedGamePlaylist"- , "TAGame.CrowdActor_TA:ReplicatedCountDownNumber"- , "TAGame.GameEvent_Soccar_TA:RoundNum"- , "TAGame.GameEvent_Soccar_TA:SecondsRemaining"- , "TAGame.GameEvent_TA:BotSkill"- , "TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining"- , "TAGame.GameEvent_TA:ReplicatedStateName"- , "TAGame.GameEvent_Team_TA:MaxTeamSize"- , "TAGame.PRI_TA:MatchAssists"- , "TAGame.PRI_TA:MatchGoals"- , "TAGame.PRI_TA:MatchSaves"- , "TAGame.PRI_TA:MatchScore"- , "TAGame.PRI_TA:MatchShots"- , "TAGame.PRI_TA:Title"- , "TAGame.PRI_TA:TotalXP"- , "TAGame.Team_Soccar_TA:GameScore"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are online loadouts.-loadoutOnlineProperties :: Set.Set StrictText.Text-loadoutOnlineProperties =- [ "TAGame.PRI_TA:ClientLoadoutOnline"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are loadouts.-loadoutProperties :: Set.Set StrictText.Text-loadoutProperties =- [ "TAGame.PRI_TA:ClientLoadout"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are locations.-locationProperties :: Set.Set StrictText.Text-locationProperties =- [ "Engine.Actor:RelativeLocation"- , "TAGame.CarComponent_Dodge_TA:DodgeTorque"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are music stingers.-musicStingerProperties :: Set.Set StrictText.Text-musicStingerProperties =- [ "TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are pickups.-pickupProperties :: Set.Set StrictText.Text-pickupProperties =- [ "TAGame.VehiclePickup_TA:ReplicatedPickupData"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are private match settings.-privateMatchSettingsProperties :: Set.Set StrictText.Text-privateMatchSettingsProperties =- [ "TAGame.GameEvent_SoccarPrivate_TA:MatchSettings"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are qwords.-qWordProperties :: Set.Set StrictText.Text-qWordProperties =- [ "ProjectX.GRI_X:GameServerID"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are relation rotations.-relativeRotationProperties :: Set.Set StrictText.Text-relativeRotationProperties =- [ "Engine.Actor:RelativeRotation"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are reservations.-reservationProperties :: Set.Set StrictText.Text-reservationProperties =- [ "ProjectX.GRI_X:Reservations"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are rigid body states.-rigidBodyStateProperties :: Set.Set StrictText.Text-rigidBodyStateProperties =- [ "TAGame.RBActor_TA:ReplicatedRBState"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are strings.-stringProperties :: Set.Set StrictText.Text-stringProperties =- [ "Engine.GameReplicationInfo:ServerName"- , "Engine.PlayerReplicationInfo:PlayerName"- , "Engine.PlayerReplicationInfo:RemoteUserData"- , "TAGame.GRI_TA:NewDedicatedServerIP"- , "TAGame.Team_TA:CustomTeamName"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are team paints.-teamPaintProperties :: Set.Set StrictText.Text-teamPaintProperties =- [ "TAGame.Car_TA:TeamPaint"- ] & map StrictText.pack & Set.fromList----- | A set of properties that are unique IDs.-uniqueIdProperties :: Set.Set StrictText.Text-uniqueIdProperties =- [ "Engine.PlayerReplicationInfo:UniqueId"- -- , "TAGame.PRI_TA:PartyLeader"- ] & map StrictText.pack & Set.fromList
− library/Octane/Data/RocketTrails.hs
@@ -1,63 +0,0 @@-module Octane.Data.RocketTrails (rocketTrails) where--import Data.Function ((&))--import qualified Data.Bimap as Bimap-import qualified Data.Text as StrictText----- | A one-to-one mapping between rocket trail IDs and their names.-rocketTrails :: Bimap.Bimap Int StrictText.Text-rocketTrails =- [ ("(Alpha Reward) Gold Rush", 32) -- AlphaReward- , ("Accelerato", 524) -- MusicalNotes- , ("Batmobile", 868) -- DarkCar- , ("Battle-Stars", 545)- , ("Bubbles", 33)- , ("Burnout", 387)- , ("Candy Corn", 578)- , ("Confetti", 34)- , ("Datastream", 35) -- Digital- , ("Flamethrower Blue", 37)- , ("Flamethrower Green", 38)- , ("Flamethrower Pink", 39)- , ("Flamethrower Purple", 40)- , ("Flamethrower Red", 41)- , ("Flamethrower", 36)- , ("Flowers", 42)- , ("Grass", 43)- , ("Hydro", 69) -- Water- , ("Ion Blue", 45) -- LightTrail- , ("Ion Green", 46)- , ("Ion Pink", 47)- , ("Ion Purple", 48)- , ("Ion Red", 49)- , ("Ion Yellow", 50)- , ("Money", 51)- , ("Nitrous", 384)- , ("Nuts & Bolts", 544)- , ("OutaTime", 626) -- GreyCar- , ("Plasma", 52)- , ("Portal - Conversion Gel", 651)- , ("Portal - Propulsion Gel", 652)- , ("Portal - Reuplsion Gel", 653)- , ("Rainbow", 59)- , ("Sacred", 44) -- HolyLight- , ("Sandstorm", 664)- , ("Slime", 60)- , ("Snowflakes", 61)- , ("Sparkles", 62)- , ("Standard Blue", 64)- , ("Standard Pink", 65)- , ("Standard Purple", 66)- , ("Standard Red", 63)- , ("Standard Yellow", 67)- , ("Sweet Tooth", 68)- , ("Thermal Blue", 54)- , ("Thermal Green", 55)- , ("Thermal Pink", 56)- , ("Thermal Purple", 57)- , ("Thermal Yellow", 58)- , ("Thermal", 53) -- Propulsion- , ("Xmas", 635) -- Presents- ] & map (\ (v, k) -> (k, StrictText.pack v)) & Bimap.fromList
− library/Octane/Data/Toppers.hs
@@ -1,78 +0,0 @@-module Octane.Data.Toppers (toppers) where--import Data.Function ((&))--import qualified Data.Bimap as Bimap-import qualified Data.Text as StrictText----- | A one-to-one mapping between topper IDs and their names.-toppers :: Bimap.Bimap Int StrictText.Text-toppers =- [ ("None", 0)- , ("(Alpha Reward) Gold Cap", 224) -- AlphaHat- , ("Antlers", 774)- , ("Beret", 775)- , ("Biker Cap", 776)- , ("Birthday Cake", 789)- , ("Blitzen", 640) -- ReindeerAntlers- , ("Bobby Helmet", 227) -- BPH- , ("Boombox", 521)- , ("Bowler", 745) -- GentlemanHat- , ("Brodie Helmet", 743) -- DoughboyHelmet- , ("Brünnhilde", 241) -- Viking_Helmet- , ("Captain's Hat", 741)- , ("Cavalier", 580) -- Tricorn- , ("Chainsaw", 795)- , ("Chef's Hat", 756)- , ("Cherry Top", 237) -- PoliceSiren- , ("Christmas Tree", 639) -- RegularChristmasTree- , ("Cockroach", 769)- , ("Cow Skull", 685)- , ("deadmau5", 796)- , ("Deerstalker", 792)- , ("Derby", 790)- , ("Devil Horns", 229)- , ("Fez", 230)- , ("Fire Helmet", 231)- , ("Foam Hat", 390) -- TourneyWinner- , ("Fruit Hat", 744)- , ("Graduation Cap", 778)- , ("Halo", 232)- , ("Hard Hat", 233)- , ("Homburg", 742) -- DetectiveHat- , ("Locomotive", 547) -- TrainConductor- , ("Mariachi Hat", 234)- , ("Mohawk", 638)- , ("Mouse Trap", 782) -- RatTrap- , ("Paper Boat", 770)- , ("Pirate's Hat", 235)- , ("Pixelated Shades", 494) -- DWI- , ("Pizza Topper", 236)- , ("Plunger", 772)- , ("Police Hat", 746)- , ("Portal - Cake", 661)- , ("Propellerhead", 225) -- Beanie- , ("Pumpkin", 546) -- CatOLantern- , ("Rasta", 771)- , ("Rhino Horns", 780)- , ("Royal Crown", 228)- , ("Sad Sapling", 641) -- SadChristmasTree- , ("Santa", 642)- , ("Season 1 - Bronze", 705)- , ("Season 1 - Gold", 706)- , ("Season 1 - Platinum", 707)- , ("Season 1 - Silver", 708)- , ("Shark Fin", 579)- , ("Shuriken", 773)- , ("Sombrero", 238)- , ("Taxi Topper", 239)- , ("Tiara", 495)- , ("Top Hat", 240)- , ("Traffic Cone", 747)- , ("Unicorn", 748) -- Unihorn- , ("Witch's Hat", 242)- , ("Wizard Hat", 243)- , ("Work Boot", 740)- , ("Worms W.M.D.", 1028)- ] & map (\ (v, k) -> (k, StrictText.pack v)) & Bimap.fromList
− library/Octane/Data/Wheels.hs
@@ -1,51 +0,0 @@-module Octane.Data.Wheels (wheels) where--import Data.Function ((&))--import qualified Data.Bimap as Bimap-import qualified Data.Text as StrictText----- | A one-to-one mapping between wheels IDs and their names.-wheels :: Bimap.Bimap Int StrictText.Text-wheels =- [ ("(Alpha Reward) Goldstone", 358) -- AlphaRim- , ("Alchemist", 374) -- Revolution- , ("Almas", 364) -- Crypt- , ("Armadillo", 618)- , ("Batmobile", 874) -- Darkcar- , ("Bender", 360) -- Ballistic- , ("Carriage", 549)- , ("Cog", 716) -- TODO: What is this called in game?- , ("Cristiano", 386) -- SoccerBall- , ("DeLorean Time Machine", 609) -- GreyCar- , ("Dieci", 363) -- Caliber- , ("Falco", 382) -- Vulcan- , ("Foreman", 372) -- OffRoad- , ("Grog", 613) -- WastelandTruck- , ("Hogsticker", 719) -- Warthog- , ("Invader", 380) -- Triad- , ("Lowrider", 369)- , ("Lucci", 361) -- Bling- , ("Mountaineer", 375) -- SnowTire- , ("Neptune", 370) -- Mob- , ("Octavian", 379) -- Tarantula- , ("OEM", 376) -- Star- , ("Rat Rod", 366) -- Dynamo- , ("Ripper", 690) -- Spiked- , ("Scarab", 540) -- Scarab- , ("Servergate", 519) -- SkullxBones- , ("Spinner", 388) -- Spinner- , ("Spyder", 371) -- Ninja- , ("Stallion", 365) -- DeepDish- , ("Stern", 368) -- Hydra- , ("Sunburt", 383) -- Wynd- , ("Sweet Tooth", 378)- , ("Tempest", 377) -- Storm- , ("Tomahawk", 362) -- Brink- , ("Trahere", 367) -- Forge- , ("Tunica", 359) -- Atlantis- , ("Veloce", 373) -- Pedigree- , ("Vortex", 381)- , ("Zippy", 518) -- SingleSpoke- ] & map (\ (v, k) -> (k, StrictText.pack v)) & Bimap.fromList
library/Octane/Type.hs view
@@ -25,6 +25,7 @@ , module Octane.Type.Stream , module Octane.Type.Text , module Octane.Type.Value+ , module Octane.Type.Vector , module Octane.Type.Word16 , module Octane.Type.Word32 , module Octane.Type.Word64@@ -57,6 +58,7 @@ import Octane.Type.Stream import Octane.Type.Text import Octane.Type.Value+import Octane.Type.Vector import Octane.Type.Word16 import Octane.Type.Word32 import Octane.Type.Word64
library/Octane/Type/Boolean.hs view
@@ -13,7 +13,11 @@ import qualified Data.Binary.Bits.Put as BinaryBit import qualified GHC.Generics as Generics +-- $setup+-- >>> import qualified Data.Binary.Get as Binary+-- >>> import qualified Data.Binary.Put as Binary + -- | A boolean value. newtype Boolean = Boolean { unpack :: Bool@@ -21,6 +25,12 @@ -- | Stored in the last bit of a byte. Decoding will fail if the byte is -- anything other than @0b00000000@ or @0b00000001@.+--+-- >>> Binary.decode "\x01" :: Boolean+-- Boolean {unpack = True}+--+-- >>> Binary.encode (Boolean True)+-- "\SOH" instance Binary.Binary Boolean where get = do value <- Binary.getWord8@@ -36,6 +46,12 @@ & Binary.putWord8 -- | Stored as a bit.+--+-- >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x80" :: Boolean+-- Boolean {unpack = True}+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (Boolean True)))+-- "\128" instance BinaryBit.BinaryBit Boolean where getBits _ = do value <- BinaryBit.getBool@@ -48,6 +64,9 @@ instance DeepSeq.NFData Boolean where -- | Encoded directly as a JSON boolean.+--+-- >>> Aeson.encode (Boolean True)+-- "true" instance Aeson.ToJSON Boolean where toJSON boolean = boolean & unpack
library/Octane/Type/CacheItem.hs view
@@ -13,7 +13,10 @@ import qualified Octane.Type.List as List import qualified Octane.Type.Word32 as Word32 +-- $setup+-- >>> :set -XOverloadedLists + -- | An item in the class net cache map. data CacheItem = CacheItem { classId :: Word32.Word32@@ -27,6 +30,12 @@ } deriving (Eq, Generics.Generic, Show) -- | Fields are stored one after the other in order.+--+-- >>> Binary.decode "\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00" :: CacheItem+-- CacheItem {classId = 0x00000001, parentCacheId = 0x00000002, cacheId = 0x00000003, properties = fromList []}+--+-- >>> Binary.encode (CacheItem 1 2 3 [])+-- "\SOH\NUL\NUL\NUL\STX\NUL\NUL\NUL\ETX\NUL\NUL\NUL\NUL\NUL\NUL\NUL" instance Binary.Binary CacheItem where get = CacheItem <$> Binary.get
library/Octane/Type/CacheProperty.hs view
@@ -21,6 +21,12 @@ } deriving (Eq, Generics.Generic, Show) -- | Fields are stored one after the other in order.+--+-- >>> Binary.decode "\x01\x00\x00\x00\x02\x00\x00\x00" :: CacheProperty+-- CacheProperty {objectId = 0x00000001, streamId = 0x00000002}+--+-- >>> Binary.encode (CacheProperty 1 2)+-- "\SOH\NUL\NUL\NUL\STX\NUL\NUL\NUL" instance Binary.Binary CacheProperty where get = CacheProperty <$> Binary.get
library/Octane/Type/ClassItem.hs view
@@ -23,6 +23,12 @@ } deriving (Eq, Generics.Generic, Show) -- | Fields are stored one after the other in order.+--+-- >>> Binary.decode "\x02\x00\x00\x00\x4b\x00\x01\x00\x00\x00" :: ClassItem+-- ClassItem {name = "K", streamId = 0x00000001}+--+-- >>> Binary.encode (ClassItem "K" 1)+-- "\STX\NUL\NUL\NULK\NUL\SOH\NUL\NUL\NUL" instance Binary.Binary ClassItem where get = ClassItem <$> Binary.get
library/Octane/Type/Dictionary.hs view
@@ -15,7 +15,11 @@ import qualified GHC.Generics as Generics import qualified Octane.Type.Text as Text +-- $setup+-- >>> import GHC.Exts+-- >>> import Octane.Type.Word8 + -- | A mapping between text and arbitrary values. newtype Dictionary a = Dictionary { unpack :: (Map.Map Text.Text a)@@ -23,6 +27,12 @@ -- | Elements are stored with the key first, then the value. The dictionary -- ends when a key is @"None"@.+--+-- >>> Binary.decode "\x02\x00\x00\x00k\x00\x01\x05\x00\x00\x00None\x00" :: Dictionary Word8+-- fromList [("k",0x01)]+--+-- >>> Binary.encode ([("k", 1)] :: Dictionary Word8)+-- "\STX\NUL\NUL\NULk\NUL\SOH\ENQ\NUL\NUL\NULNone\NUL" instance (Binary.Binary a) => Binary.Binary (Dictionary a) where get = do element <- getElement@@ -38,6 +48,9 @@ -- | Allows creating 'Dictionary' values with 'Exts.fromList'. Also allows -- 'Dictionary' literals with the @OverloadedLists@ extension.+--+-- >>> [("one", 1)] :: Dictionary Int+-- fromList [("one",1)] instance Exts.IsList (Dictionary a) where type Item (Dictionary a) = (Text.Text, a) @@ -47,11 +60,17 @@ instance (DeepSeq.NFData a) => DeepSeq.NFData (Dictionary a) where --- | Shown as @fromList [("key", "value")]@.+-- | Shown as @fromList [("key","value")]@.+--+-- >>> show ([("one", 1)] :: Dictionary Int)+-- "fromList [(\"one\",1)]" instance (Show a) => Show (Dictionary a) where show dictionary = show (unpack dictionary) -- | Encoded directly as a JSON object.+--+-- >>> Aeson.encode ([("one", 1)] :: Dictionary Int)+-- "{\"one\":1}" instance (Aeson.ToJSON a) => Aeson.ToJSON (Dictionary a) where toJSON dictionary = dictionary & unpack
library/Octane/Type/Float32.hs view
@@ -19,13 +19,21 @@ import qualified GHC.Generics as Generics import qualified Octane.Utility.Endian as Endian +-- $setup+-- >>> import qualified Data.Binary.Get as Binary+-- >>> import qualified Data.Binary.Put as Binary + -- | A 32-bit float. newtype Float32 = Float32 { unpack :: Float } deriving (Eq, Fractional, Generics.Generic, Num, Ord) --- | Stored little-endian.+-- | >>> Binary.decode "\x9a\x99\x99\x3f" :: Float32+-- 1.2+--+-- >>> Binary.encode (1.2 :: Float32)+-- "\154\153\153?" instance Binary.Binary Float32 where get = do value <- IEEE754.getFloat32le@@ -35,7 +43,11 @@ & unpack & IEEE754.putFloat32le --- | Stored little-endian with the bits in each byte reversed.+-- | >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x59\x99\x99\xfc" :: Float32+-- 1.2+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (1.2 :: Float32)))+-- "Y\153\153\252" instance BinaryBit.BinaryBit Float32 where getBits _ = do bytes <- BinaryBit.getByteString 4@@ -55,10 +67,16 @@ instance DeepSeq.NFData Float32 -- | Shown as @12.34@.+--+-- >>> show (1.2 :: Float32)+-- "1.2" instance Show Float32 where show float32 = show (unpack float32) -- | Encoded directly as a JSON number.+--+-- Aeson.encode (1.2 :: Float32)+-- "1.2" instance Aeson.ToJSON Float32 where toJSON float32 = float32 & unpack
library/Octane/Type/Frame.hs view
@@ -18,7 +18,6 @@ import qualified Octane.Data as Data import qualified Octane.Type.Float32 as Float32 import qualified Octane.Type.Initialization as Initialization-import qualified Octane.Type.RemoteId as RemoteId import qualified Octane.Type.Replication as Replication import qualified Octane.Type.State as State import qualified Octane.Type.Value as Value@@ -27,6 +26,9 @@ -- | A frame in the network stream. This holds all the interesting game data.+--+-- This cannot be an instance of 'Data.Binary.Bits.BinaryBit' because it+-- requires out-of-band information (the class property map) to decode. data Frame = Frame { number :: Word -- ^ This frame's number in the network stream. Starts at 0.@@ -138,7 +140,7 @@ Value.VGameMode _ -> "GameMode" Value.VInt _ -> "Int" Value.VLoadout _ _ _ _ _ _ _ _ _ -> "Loadout"- Value.VLoadoutOnline _ _ _ _ -> "OnlineLoadout"+ Value.VLoadoutOnline _ -> "OnlineLoadout" Value.VLocation _ -> "Position" Value.VMusicStinger _ _ _ -> "MusicStinger" Value.VPickup _ _ _ -> "Pickup"@@ -178,32 +180,32 @@ [ ("Version", Aeson.toJSON version) , ("Body", Aeson.object [ ("Id", Aeson.toJSON body)- , ("Name", body & getBody & Aeson.toJSON)+ , ("Name", body & getProduct & Aeson.toJSON) ]) , ("Decal", Aeson.object [ ("Id", Aeson.toJSON decal)- , ("Name", decal & getDecal & Aeson.toJSON)+ , ("Name", decal & getProduct & Aeson.toJSON) ]) , ("Wheels", Aeson.object [ ("Id", Aeson.toJSON wheels)- , ("Name", wheels & getWheels & Aeson.toJSON)+ , ("Name", wheels & getProduct & Aeson.toJSON) ]) , ("RocketTrail", Aeson.object [ ("Id", Aeson.toJSON rocketTrail)- , ("Name", rocketTrail & getRocketTrail & Aeson.toJSON)+ , ("Name", rocketTrail & getProduct & Aeson.toJSON) ]) , ("Antenna", Aeson.object [ ("Id", Aeson.toJSON antenna)- , ("Name", antenna & getAntenna & Aeson.toJSON)+ , ("Name", antenna & getProduct & Aeson.toJSON) ]) , ("Topper", Aeson.object [ ("Id", Aeson.toJSON topper)- , ("Name", topper & getTopper & Aeson.toJSON)+ , ("Name", topper & getProduct & Aeson.toJSON) ]) , ("Unknown1", Aeson.toJSON x) , ("Unknown2", Aeson.toJSON y) ]- Value.VLoadoutOnline a b c d -> Aeson.toJSON (a, b, c, d)+ Value.VLoadoutOnline a -> Aeson.toJSON a Value.VLocation x -> Aeson.toJSON x Value.VMusicStinger a b c -> Aeson.toJSON (a, b, c) Value.VPickup a b c -> Aeson.toJSON (a, b, c)@@ -240,11 +242,11 @@ , ("AccentColor", Aeson.toJSON color2) , ("PrimaryFinish", Aeson.object [ ("Id", Aeson.toJSON finish1)- , ("Name", finish1 & getFinish & Aeson.toJSON)+ , ("Name", finish1 & getProduct & Aeson.toJSON) ]) , ("AccentFinish", Aeson.object [ ("Id", Aeson.toJSON finish2)- , ("Name", finish2 & getFinish & Aeson.toJSON)+ , ("Name", finish2 & getProduct & Aeson.toJSON) ]) ] Value.VUniqueId systemId remoteId localId -> Aeson.object@@ -254,11 +256,7 @@ 2 -> "PlayStation" 4 -> "Xbox" _ -> Aeson.String ("Unknown system " <> StrictText.pack (show systemId)))- , ("Remote", case remoteId of- RemoteId.SplitscreenId x -> Aeson.toJSON x- RemoteId.SteamId x -> Aeson.toJSON x- RemoteId.PlayStationId x -> Aeson.toJSON x- RemoteId.XboxId x -> Aeson.toJSON x)+ , ("Remote", Aeson.toJSON remoteId) , ("Local", Aeson.toJSON localId) ] @@ -267,29 +265,5 @@ getGameMode x = Bimap.lookup (Word8.fromWord8 x) Data.gameModes -getBody :: Word32.Word32 -> Maybe StrictText.Text-getBody x = Bimap.lookup (Word32.fromWord32 x) Data.bodies---getDecal :: Word32.Word32 -> Maybe StrictText.Text-getDecal x = Bimap.lookup (Word32.fromWord32 x) Data.decals---getWheels :: Word32.Word32 -> Maybe StrictText.Text-getWheels x = Bimap.lookup (Word32.fromWord32 x) Data.wheels---getRocketTrail :: Word32.Word32 -> Maybe StrictText.Text-getRocketTrail x = Bimap.lookup (Word32.fromWord32 x) Data.rocketTrails---getAntenna :: Word32.Word32 -> Maybe StrictText.Text-getAntenna x = Bimap.lookup (Word32.fromWord32 x) Data.antennas---getTopper :: Word32.Word32 -> Maybe StrictText.Text-getTopper x = Bimap.lookup (Word32.fromWord32 x) Data.toppers---getFinish :: Word32.Word32 -> Maybe StrictText.Text-getFinish x = Bimap.lookup (Word32.fromWord32 x) Data.finishes+getProduct :: Word32.Word32 -> Maybe StrictText.Text+getProduct x = Bimap.lookup (Word32.fromWord32 x) Data.products
library/Octane/Type/Initialization.hs view
@@ -11,6 +11,9 @@ -- | Information about a new instance of a class.+--+-- This cannot be an instance of 'Data.Binary.Bits.BinaryBit' because it+-- requires out-of-band information (the class name) to decode. data Initialization = Initialization { location :: Maybe (Vector.Vector Int) -- ^ The instance's initial position.
library/Octane/Type/Int32.hs view
@@ -25,7 +25,11 @@ { unpack :: Int.Int32 } deriving (Eq, Generics.Generic, Num, Ord) --- | Stored in little-endian byte order.+-- | >>> Binary.decode "\x01\x00\x00\x00" :: Int32+-- 1+--+-- >>> Binary.encode (1 :: Int32)+-- "\SOH\NUL\NUL\NUL" instance Binary.Binary Int32 where get = do value <- Binary.getInt32le@@ -35,7 +39,11 @@ let value = unpack int32 Binary.putInt32le value --- | Store little-endian with the bits in each byte reversed.+-- | >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x80\x00\x00\x00" :: Int32+-- 1+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (1 :: Int32)))+-- "\128\NUL\NUL\NUL" instance BinaryBit.BinaryBit Int32 where getBits _ = do bytes <- BinaryBit.getByteString 4@@ -55,10 +63,16 @@ instance DeepSeq.NFData Int32 where -- | Shown as @1234@.+--+-- show (1 :: Int32)+-- "1" instance Show Int32 where show int32 = show (unpack int32) -- | Encoded as a JSON number directly.+--+-- >>> Aeson.encode (1 :: Int32)+-- "1" instance Aeson.ToJSON Int32 where toJSON int32 = int32 & unpack
library/Octane/Type/Int8.hs view
@@ -19,12 +19,21 @@ import qualified GHC.Generics as Generics import qualified Octane.Utility.Endian as Endian +-- $setup+-- >>> import qualified Data.Binary.Get as Binary+-- >>> import qualified Data.Binary.Put as Binary + -- | A 8-bit signed integer. newtype Int8 = Int8 { unpack :: Int.Int8 } deriving (Eq, Generics.Generic, Num, Ord) +-- | >>> Binary.decode "\x01" :: Int8+-- 1+--+-- >>> Binary.encode (1 :: Int8)+-- "\SOH" instance Binary.Binary Int8 where get = do value <- Binary.getInt8@@ -35,6 +44,12 @@ Binary.putInt8 value -- | Stored with the bits reversed.+--+-- >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x80" :: Int8+-- 1+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (1 :: Int8)))+-- "\128" instance BinaryBit.BinaryBit Int8 where getBits _ = do bytes <- BinaryBit.getByteString 1@@ -54,10 +69,16 @@ instance DeepSeq.NFData Int8 where -- | Shown as @1234@.+--+-- show (1 :: Int8)+-- "1" instance Show Int8 where show int8 = show (unpack int8) -- | Encoded directly as a JSON number.+--+-- >>> Aeson.encode (1 :: Int8)+-- "1" instance Aeson.ToJSON Int8 where toJSON int8 = int8 & unpack
library/Octane/Type/KeyFrame.hs view
@@ -24,6 +24,12 @@ } deriving (Eq, Generics.Generic, Show) -- | Stored with the fields one after the other in order.+--+-- >>> Binary.decode "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00" :: KeyFrame+-- KeyFrame {time = 0.0, frame = 0x00000001, position = 0x00000002}+--+-- >>> Binary.encode (KeyFrame { time = 0, frame = 1, position = 2 })+-- "\NUL\NUL\NUL\NUL\SOH\NUL\NUL\NUL\STX\NUL\NUL\NUL" instance Binary.Binary KeyFrame where get = KeyFrame <$> Binary.get
library/Octane/Type/List.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE TypeFamilies #-} module Octane.Type.List (List(..)) where @@ -9,16 +10,26 @@ import qualified Control.Monad as Monad import qualified Data.Aeson as Aeson import qualified Data.Binary as Binary+import qualified GHC.Exts as Exts import qualified GHC.Generics as Generics import qualified Octane.Type.Word32 as Word32 +-- $setup+-- >>> import Octane.Type.Int8 --- | A list of valeus.++-- | A list of values. newtype List a = List { unpack :: [a]- } deriving (Eq, Generics.Generic, Ord, Show)+ } deriving (Eq, Generics.Generic, Ord) -- | Prefixed with the number of elements in the list.+--+-- >>> Binary.decode "\x01\x00\x00\x00\x02" :: List Int8+-- fromList [2]+--+-- >>> Binary.encode ([2] :: List Int8)+-- "\SOH\NUL\NUL\NUL\STX" instance (Binary.Binary a) => Binary.Binary (List a) where get = do size <- Binary.get@@ -29,9 +40,29 @@ list & unpack & length & fromIntegral & Word32.Word32 & Binary.put list & unpack & mapM_ Binary.put +-- | Allows creating 'List' values with 'Exts.fromList'. Also allows 'List'+-- literals with the @OverloadedLists@ extension.+--+-- >>> [2] :: List Int+-- fromList [2]+instance Exts.IsList (List a) where+ type Item (List a) = a++ fromList items = List items++ toList list = unpack list+ instance (DeepSeq.NFData a) => DeepSeq.NFData (List a) where +-- | >>> show ([2] :: List Int)+-- "fromList [2]"+instance (Show a) => Show (List a) where+ show list = "fromList " ++ show (unpack list)+ -- | Encoded as a JSON array directly.+--+-- >>> Aeson.encode ([2] :: List Int)+-- "[2]" instance (Aeson.ToJSON a) => Aeson.ToJSON (List a) where toJSON list = list & unpack
library/Octane/Type/Mark.hs view
@@ -22,6 +22,12 @@ } deriving (Eq, Generics.Generic, Show) -- | Fields are stored one after the other in order.+--+-- >>> Binary.decode "\x02\x00\x00\x00\x4b\x00\x01\x00\x00\x00" :: Mark+-- Mark {label = "K", frame = 0x00000001}+--+-- >>> Binary.encode (Mark "K" 1)+-- "\STX\NUL\NUL\NULK\NUL\SOH\NUL\NUL\NUL" instance Binary.Binary Mark where get = Mark <$> Binary.get
library/Octane/Type/Message.hs view
@@ -23,6 +23,12 @@ } deriving (Eq, Generics.Generic, Show) -- | Fields stored in order, one after the other.+--+-- >>> Binary.decode "\x01\x00\x00\x00\x02\x00\x00\x00\x41\x00\x02\x00\x00\x00\x42\x00" :: Message+-- Message {frame = 0x00000001, name = "A", content = "B"}+--+-- >>> Binary.encode (Message 1 "A" "B")+-- "\SOH\NUL\NUL\NUL\STX\NUL\NUL\NULA\NUL\STX\NUL\NUL\NULB\NUL" instance Binary.Binary Message where get = Message <$> Binary.get
library/Octane/Type/RemoteId.hs view
@@ -3,47 +3,218 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE StrictData #-} -module Octane.Type.RemoteId (RemoteId(..)) where+module Octane.Type.RemoteId+ ( RemoteId(..)+ , SteamId(..)+ , PlayStationId(..)+ , SplitscreenId(..)+ , XboxId(..)+ ) where import Data.Aeson ((.=))+import Data.Function ((&)) import qualified Control.DeepSeq as DeepSeq import qualified Data.Aeson as Aeson+import qualified Data.Binary.Bits as BinaryBit+import qualified Data.Binary.Bits.Get as BinaryBit+import qualified Data.Binary.Bits.Put as BinaryBit+import qualified Data.ByteString.Lazy as LazyBytes+import qualified Data.Text as StrictText+import qualified Data.Text.Encoding as Encoding import qualified GHC.Generics as Generics import qualified Octane.Type.Text as Text import qualified Octane.Type.Word64 as Word64+import qualified Octane.Utility.Endian as Endian+import qualified Text.Printf as Printf +-- $setup+-- >>> import qualified Data.Binary.Get as Binary+-- >>> import qualified Data.Binary.Put as Binary -- | A player's canonical remote ID. This is the best way to uniquely identify--- players.+-- players data RemoteId- = SteamId Word64.Word64- -- ^ A Steam ID.- | PlayStationId Text.Text- -- ^ A PlayStation Network ID.- | SplitscreenId (Maybe Int)- -- ^ A local splitscreen ID.- | XboxId Word64.Word64- -- ^ An Xbox Live ID.+ = RemotePlayStationId PlayStationId+ | RemoteSplitscreenId SplitscreenId+ | RemoteSteamId SteamId+ | RemoteXboxId XboxId deriving (Eq, Generics.Generic, Show) instance DeepSeq.NFData RemoteId where +-- | Encodes the remote ID as an object with "Type" and "Value" keys.+--+-- >>> Aeson.encode (RemoteSteamId (SteamId 1))+-- "{\"Value\":1,\"Type\":\"Steam\"}" instance Aeson.ToJSON RemoteId where toJSON remoteId = case remoteId of- PlayStationId x -> Aeson.object+ RemotePlayStationId x -> Aeson.object [ "Type" .= ("PlayStation" :: Text.Text)- , "Value" .= x+ , "Value" .= Aeson.toJSON x ]- SplitscreenId x -> Aeson.object+ RemoteSplitscreenId x -> Aeson.object [ "Type" .= ("Splitscreen" :: Text.Text)- , "Value" .= x+ , "Value" .= Aeson.toJSON x ]- SteamId x -> Aeson.object+ RemoteSteamId x -> Aeson.object [ "Type" .= ("Steam" :: Text.Text)- , "Value" .= x+ , "Value" .= Aeson.toJSON x ]- XboxId x -> Aeson.object+ RemoteXboxId x -> Aeson.object [ "Type" .= ("Xbox" :: Text.Text)- , "Value" .= x+ , "Value" .= Aeson.toJSON x ]+++data PlayStationId = PlayStationId+ { playStationName :: Text.Text+ , playStationUnknown :: LazyBytes.ByteString+ } deriving (Eq, Generics.Generic, Show)++-- | Each part is stored as exactly 16 bits.+--+-- >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x42\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80" :: PlayStationId+-- PlayStationId {playStationName = "B", playStationUnknown = "\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\SOH"}+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (PlayStationId "A" "\x01")))+-- "\130\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\128"+instance BinaryBit.BinaryBit PlayStationId where+ getBits _ = do+ nameBytes <- BinaryBit.getByteString 16+ let name = nameBytes+ & Endian.reverseBitsInStrictBytes+ & Encoding.decodeLatin1+ & StrictText.dropWhileEnd (== '\0')+ & Text.Text++ unknownBytes <- BinaryBit.getByteString 16+ let unknown = unknownBytes+ & Endian.reverseBitsInStrictBytes+ & LazyBytes.fromStrict++ pure (PlayStationId name unknown)++ putBits _ playStationId = do+ playStationId+ & playStationName+ & Text.unpack+ & StrictText.justifyLeft 16 '\x00'+ & StrictText.take 16+ & Text.encodeLatin1+ & Endian.reverseBitsInStrictBytes+ & BinaryBit.putByteString++ playStationId+ & playStationUnknown+ & LazyBytes.toStrict+ & Endian.reverseBitsInStrictBytes+ & BinaryBit.putByteString++instance DeepSeq.NFData PlayStationId where++-- | >>> Aeson.encode (PlayStationId "A" "B")+-- "{\"Unknown\":\"0x42\",\"Name\":\"A\"}"+instance Aeson.ToJSON PlayStationId where+ toJSON playStationId = Aeson.object+ [ "Name" .= playStationName playStationId+ , "Unknown" .= (playStationId+ & playStationUnknown+ & LazyBytes.unpack+ & concatMap (Printf.printf "%02x")+ & ("0x" ++)+ & StrictText.pack)+ ]+++newtype SplitscreenId = SplitscreenId+ { unpackSplitscreenId :: Maybe Int+ } deriving (Eq, Generics.Generic, Show)++-- | Stored as a bare byte string.+--+-- >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x00\x00\x00" :: SplitscreenId+-- SplitscreenId {unpackSplitscreenId = Just 0}+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (SplitscreenId (Just 0))))+-- "\NUL\NUL\NUL"+instance BinaryBit.BinaryBit SplitscreenId where+ getBits _ = do+ bytes <- BinaryBit.getByteString 3+ case bytes of+ "\x00\x00\x00" -> do+ pure (SplitscreenId (Just 0))+ _ -> do+ fail ("Unexpected SplitscreenId value " ++ show bytes)++ putBits _ _splitscreenId = do+ BinaryBit.putByteString "\x00\x00\x00"++instance DeepSeq.NFData SplitscreenId where++-- | Encoded as an optional number.+--+-- >>> Aeson.encode (SplitscreenId Nothing)+-- "null"+--+-- >>> Aeson.encode (SplitscreenId (Just 0))+-- "0"+instance Aeson.ToJSON SplitscreenId where+ toJSON splitscreenId = splitscreenId & unpackSplitscreenId & Aeson.toJSON+++newtype SteamId = SteamId+ { unpackSteamId :: Word64.Word64+ } deriving (Eq, Generics.Generic, Show)++-- | Stored as a plain 'Word64.Word64'.+--+-- >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x80\x00\x00\x00\x00\x00\x00\x00" :: SteamId+-- SteamId {unpackSteamId = 0x0000000000000001}+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (SteamId 1)))+-- "\128\NUL\NUL\NUL\NUL\NUL\NUL\NUL"+instance BinaryBit.BinaryBit SteamId where+ getBits _ = do+ steamId <- BinaryBit.getBits 0+ pure (SteamId steamId)++ putBits _ steamId = steamId & unpackSteamId & BinaryBit.putBits 0++instance DeepSeq.NFData SteamId where++-- | Encoded directly as a number.+--+-- >>> Aeson.encode (SteamId 1)+-- "1"+instance Aeson.ToJSON SteamId where+ toJSON steamId = steamId & unpackSteamId & Aeson.toJSON+++newtype XboxId = XboxId+ { unpackXboxId :: Word64.Word64+ } deriving (Eq, Generics.Generic, Show)++-- | Stored as a plain 'Word64.Word64'.+--+-- >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x80\x00\x00\x00\x00\x00\x00\x00" :: XboxId+-- XboxId {unpackXboxId = 0x0000000000000001}+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (XboxId 1)))+-- "\128\NUL\NUL\NUL\NUL\NUL\NUL\NUL"+instance BinaryBit.BinaryBit XboxId where+ getBits _ = do+ xboxId <- BinaryBit.getBits 0+ pure (XboxId xboxId)++ putBits _ xboxId = xboxId & unpackXboxId & BinaryBit.putBits 0+++instance DeepSeq.NFData XboxId where++-- | Encoded directly as a number.+--+-- >>> Aeson.encode (XboxId 1)+-- "1"+instance Aeson.ToJSON XboxId where+ toJSON xboxId = xboxId & unpackXboxId & Aeson.toJSON
library/Octane/Type/Replication.hs view
@@ -14,6 +14,9 @@ -- | A replicated actor in a frame.+--+-- This cannot be an instance of 'Data.Binary.Bits.BinaryBit' because it+-- requires out-of-band information (the class property map) to decode. data Replication = Replication { actorId :: Word -- ^ The actor's ID.
library/Octane/Type/Stream.hs view
@@ -23,6 +23,12 @@ -- | Prefixed by a length in bytes. Each byte is reversed such that -- @0b01234567@ is actually @0b76543210@.+--+-- >>> Binary.decode "\x01\x00\x00\x00\x0f" :: Stream+-- Stream {unpack = "1 byte"}+--+-- >>> Binary.encode (Stream "\xf0")+-- "\SOH\NUL\NUL\NUL\SI" instance Binary.Binary Stream where get = do size <- Binary.get@@ -35,6 +41,10 @@ instance DeepSeq.NFData Stream where +-- | Doesn't show the actual bytes to avoid dumping tons of text.+--+-- >>> show (Stream "\xf0")+-- "Stream {unpack = \"1 byte\"}" instance Show Stream where show stream = do let size = stream & unpack & LazyBytes.length
library/Octane/Type/Text.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE OverloadedStrings #-} -module Octane.Type.Text (Text(..)) where+module Octane.Type.Text (Text(..), encodeLatin1) where import Data.Function ((&)) @@ -23,13 +23,23 @@ import qualified Octane.Type.Int32 as Int32 import qualified Octane.Utility.Endian as Endian +-- $setup+-- >>> import qualified Data.Binary.Get as Binary+-- >>> import qualified Data.Binary.Put as Binary + -- | A thin wrapper around 'StrictText.Text'. newtype Text = Text { unpack :: StrictText.Text } deriving (Eq, Generics.Generic, Ord) -- | Text is both length-prefixed and null-terminated.+--+-- >>> Binary.decode "\x02\x00\x00\x00\x4b\x00" :: Text+-- "K"+--+-- >>> Binary.encode ("K" :: Text)+-- "\STX\NUL\NUL\NULK\NUL" instance Binary.Binary Text where get = getText Binary.get@@ -44,6 +54,12 @@ -- | Both length-prefixed and null-terminated. The bits in each byte are -- reversed.+--+-- >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x40\x00\x00\x00\xd2\x00" :: Text+-- "K"+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 ("K" :: Text)))+-- "@\NUL\NUL\NUL\210\NUL" instance BinaryBit.BinaryBit Text where getBits _ = getText (BinaryBit.getBits 32)@@ -58,23 +74,37 @@ -- | Allows you to write 'Text' as string literals with @OverloadedStrings@. -- Also allows using the 'String.fromString' helper function.+--+-- >>> "K" :: Text+-- "K" instance String.IsString Text where fromString string = Text (StrictText.pack string) instance DeepSeq.NFData Text where -- | Shown as a string literal, like @"this"@.+--+-- >>> show ("K" :: Text)+-- "\"K\"" instance Show Text where show text = show (unpack text) -- | Encoded directly as a JSON string.+--+-- >>> Aeson.encode ("K" :: Text)+-- "\"K\"" instance Aeson.ToJSON Text where toJSON text = text & unpack & Aeson.toJSON -getText :: (Monad m) => (m Int32.Int32) -> (Int -> m StrictBytes.ByteString) -> (StrictBytes.ByteString -> StrictBytes.ByteString) -> m Text+getText+ :: (Monad m)+ => (m Int32.Int32)+ -> (Int -> m StrictBytes.ByteString)+ -> (StrictBytes.ByteString -> StrictBytes.ByteString)+ -> m Text getText getInt getBytes convertBytes = do (Int32.Int32 rawSize) <- getInt (size, decode) <-@@ -101,7 +131,13 @@ _ -> fail ("Unexpected Text value " ++ show rawText) -putText :: (Monad m) => (Int32.Int32 -> m ()) -> (StrictBytes.ByteString -> m ()) -> (StrictBytes.ByteString -> StrictBytes.ByteString) -> Text -> m ()+putText+ :: (Monad m)+ => (Int32.Int32 -> m ())+ -> (StrictBytes.ByteString -> m ())+ -> (StrictBytes.ByteString -> StrictBytes.ByteString)+ -> Text+ -> m () putText putInt putBytes convertBytes text = do let fullText = text & unpack & flip StrictText.snoc '\NUL' let size = fullText & StrictText.length & fromIntegral@@ -114,6 +150,11 @@ fullText & Encoding.encodeUtf16LE & convertBytes & putBytes +-- | Encodes text as Latin-1. Note that this isn't really safe if the text has+-- characters that can't be encoded in Latin-1.+--+-- >>> encodeLatin1 "A"+-- "A" encodeLatin1 :: StrictText.Text -> StrictBytes.ByteString encodeLatin1 text = text & StrictText.unpack
library/Octane/Type/Value.hs view
@@ -65,10 +65,7 @@ Word32.Word32 (Maybe Word32.Word32) | VLoadoutOnline- Word32.Word32- Word32.Word32- Word32.Word32- (Maybe Word8.Word8)+ [[(Word32.Word32, Int)]] | VLocation (Vector.Vector Int) | VMusicStinger
library/Octane/Type/Vector.hs view
@@ -11,6 +11,10 @@ -- | Three values packed together. Although the fields are called @x@, @y@, and -- @z@, that may not be what they actually represent.+--+-- This cannot be an instance of 'Data.Binary.Bits.BinaryBit' because it is not+-- always serialized the same way. Sometimes it is three values run together,+-- but other times it has a flag for the presence of each value. data Vector a = Vector { x :: a , y :: a@@ -20,6 +24,9 @@ instance (DeepSeq.NFData a) => DeepSeq.NFData (Vector a) where -- | Encoded as a JSON array with 3 elements.+--+-- Aeson.encode (Vector 1 2 3 :: Vector Int)+-- "[1,2,3]" instance (Aeson.ToJSON a) => Aeson.ToJSON (Vector a) where toJSON vector = Aeson.toJSON [ x vector
library/Octane/Type/Word16.hs view
@@ -21,7 +21,11 @@ { unpack :: Word.Word16 } deriving (Eq, Generics.Generic, Num, Ord) --- | Stored in little-endian byte order.+-- | >>> Binary.decode "\x01\x00" :: Word16+-- 0x0001+--+-- >>> Binary.encode (1 :: Word16)+-- "\SOH\NUL" instance Binary.Binary Word16 where get = do value <- Binary.getWord16le@@ -34,10 +38,16 @@ instance DeepSeq.NFData Word16 where -- | Shown as @0x0102@.+--+-- >>> show (1 :: Word16)+-- "0x0001" instance Show Word16 where show word16 = Printf.printf "0x%04x" (unpack word16) -- | Encoded as a JSON number.+--+-- >>> Aeson.encode (1 :: Word16)+-- "1" instance Aeson.ToJSON Word16 where toJSON word16 = word16 & unpack
library/Octane/Type/Word32.hs view
@@ -20,13 +20,21 @@ import qualified Octane.Utility.Endian as Endian import qualified Text.Printf as Printf +-- $setup+-- >>> import qualified Data.Binary.Get as Binary+-- >>> import qualified Data.Binary.Put as Binary + -- | A 32-bit unsigned integer. newtype Word32 = Word32 { unpack :: Word.Word32 } deriving (Eq, Generics.Generic, Num, Ord) --- | Stored in little-endian byte order.+-- | >>> Binary.decode "\x01\x00\x00\x00" :: Word32+-- 0x00000001+--+-- >>> Binary.encode (1 :: Word32)+-- "\SOH\NUL\NUL\NUL" instance Binary.Binary Word32 where get = do value <- Binary.getWord32le@@ -36,7 +44,11 @@ let value = unpack word32 Binary.putWord32le value --- | Little-endian with the bits in each byte reversed.+-- | >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x80\x00\x00\x00" :: Word32+-- 0x00000001+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (1 :: Word32)))+-- "\128\NUL\NUL\NUL" instance BinaryBit.BinaryBit Word32 where getBits _ = do bytes <- BinaryBit.getByteString 4@@ -56,10 +68,16 @@ instance DeepSeq.NFData Word32 where -- | Shown as @0x01020304@.+--+-- >>> show (1 :: Word32)+-- "0x00000001" instance Show Word32 where show word32 = Printf.printf "0x%08x" (unpack word32) -- | Encoded as a JSON number.+--+-- >>> Aeson.encode (1 :: Word32)+-- "1" instance Aeson.ToJSON Word32 where toJSON word32 = word32 & unpack
library/Octane/Type/Word64.hs view
@@ -20,13 +20,21 @@ import qualified Octane.Utility.Endian as Endian import qualified Text.Printf as Printf +-- $setup+-- >>> import qualified Data.Binary.Get as Binary+-- >>> import qualified Data.Binary.Put as Binary + -- | A 64-bit unsigned integer. newtype Word64 = Word64 { unpack :: Word.Word64 } deriving (Eq, Generics.Generic, Num, Ord) --- | Stored in little-endian byte order.+-- | >>> Binary.decode "\x01\x00\x00\x00\x00\x00\x00\x00" :: Word64+-- 0x0000000000000001+--+-- >>> Binary.encode (1 :: Word64)+-- "\SOH\NUL\NUL\NUL\NUL\NUL\NUL\NUL" instance Binary.Binary Word64 where get = do value <- Binary.getWord64le@@ -36,7 +44,11 @@ let value = unpack word64 Binary.putWord64le value --- | Little-endian with the bits in each byte reversed.+-- | >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x80\x00\x00\x00\x00\x00\x00\x00" :: Word64+-- 0x0000000000000001+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (1 :: Word64)))+-- "\128\NUL\NUL\NUL\NUL\NUL\NUL\NUL" instance BinaryBit.BinaryBit Word64 where getBits _ = do bytes <- BinaryBit.getByteString 8@@ -55,11 +67,17 @@ instance DeepSeq.NFData Word64 where --- | Shown as @0x01020304@.+-- | Shown as @0x0102030405060708@.+--+-- >>> show (1 :: Word64)+-- "0x0000000000000001" instance Show Word64 where show word64 = Printf.printf "0x%016x" (unpack word64) -- | Encoded as a JSON number.+--+-- >>> Aeson.encode (1 :: Word64)+-- "1" instance Aeson.ToJSON Word64 where toJSON word64 = word64 & unpack
library/Octane/Type/Word8.hs view
@@ -20,12 +20,21 @@ import qualified Octane.Utility.Endian as Endian import qualified Text.Printf as Printf +-- $setup+-- >>> import qualified Data.Binary.Get as Binary+-- >>> import qualified Data.Binary.Put as Binary + -- | A 8-bit unsigned integer. newtype Word8 = Word8 { unpack :: Word.Word8 } deriving (Eq, Generics.Generic, Num, Ord) +-- | >>> Binary.decode "\x01" :: Word8+-- 0x01+--+-- >>> Binary.encode (1 :: Word8)+-- "\SOH" instance Binary.Binary Word8 where get = do value <- Binary.getWord8@@ -36,6 +45,12 @@ Binary.putWord8 value -- | The bits are reversed.+--+-- >>> Binary.runGet (BinaryBit.runBitGet (BinaryBit.getBits 0)) "\x80" :: Word8+-- 0x01+--+-- >>> Binary.runPut (BinaryBit.runBitPut (BinaryBit.putBits 0 (1 :: Word8)))+-- "\128" instance BinaryBit.BinaryBit Word8 where getBits _ = do bytes <- BinaryBit.getByteString 1@@ -55,10 +70,16 @@ instance DeepSeq.NFData Word8 where -- | Shown as @0x01@.+--+-- >>> show (1 :: Word8)+-- "0x01" instance Show Word8 where show word8 = Printf.printf "0x%02x" (unpack word8) -- | Encoded as a JSON number.+--+-- >>> Aeson.encode (1 :: Word8)+-- "1" instance Aeson.ToJSON Word8 where toJSON word8 = word8 & unpack
library/Octane/Utility.hs view
@@ -1,11 +1,15 @@ module Octane.Utility ( module Octane.Utility.ClassPropertyMap , module Octane.Utility.CRC+ , module Octane.Utility.Embed , module Octane.Utility.Endian , module Octane.Utility.Optimizer+ , module Octane.Utility.Parser ) where import Octane.Utility.ClassPropertyMap import Octane.Utility.CRC+import Octane.Utility.Embed import Octane.Utility.Endian import Octane.Utility.Optimizer+import Octane.Utility.Parser
library/Octane/Utility/CRC.hs view
@@ -9,10 +9,10 @@ -- | Computes the CRC32 of some bytes. Note that this is a non-standard CRC32. -- It probably only works for Rocket League. ----- >>> crc32 LazyBytes.empty -- ""+-- >>> crc32 "" -- 4023120385 ----- >>> crc32 (LazyBytes.pack [49 .. 57]) -- "123456789"+-- >>> crc32 "123456789" -- 3690624627 crc32 :: LazyBytes.ByteString -> Word.Word32 crc32 bytes = do
library/Octane/Utility/ClassPropertyMap.hs view
@@ -10,7 +10,6 @@ import Data.Function ((&)) -import qualified Data.Char as Char import qualified Data.IntMap.Strict as IntMap import qualified Data.List as List import qualified Data.Map.Strict as Map@@ -23,6 +22,7 @@ import qualified Octane.Type.ReplayWithoutFrames as ReplayWithoutFrames import qualified Octane.Type.Text as Text import qualified Octane.Type.Word32 as Word32+import qualified Text.Regex as Regex -- | The class property map is a map from class IDs in the stream to a map from@@ -169,21 +169,55 @@ -- | Gets the class ID and name for a given property ID. getClass- :: IntMap.IntMap StrictText.Text -- ^ Property ID to property name+ :: (Monad m)+ => IntMap.IntMap StrictText.Text -- ^ Property ID to property name -> Map.Map StrictText.Text StrictText.Text -- ^ Property name to class name -> Map.Map StrictText.Text Int -- ^ Class name to class ID -> Int -- ^ property ID- -> Maybe (Int, StrictText.Text) -- ^ Maybe class ID and class name-getClass propertyIdsToNames propertyNamesToClassNames classNamesToIds propertyId =- case IntMap.lookup propertyId propertyIdsToNames of- Nothing -> Nothing- Just rawPropertyName -> let- -- There are a large number of properties that end in numbers that- -- should all be treated the same. Instead of explicitly mapping- -- each of them, we can remove the numbers and treat them the same.- propertyName = rawPropertyName & StrictText.dropWhileEnd Char.isDigit- in case Map.lookup propertyName propertyNamesToClassNames of- Nothing -> Nothing- Just className -> case Map.lookup className classNamesToIds of- Nothing -> Nothing- Just classId -> Just (classId, className)+ -> m (Int, StrictText.Text) -- ^ Maybe class ID and class name+getClass propertyIdsToNames propertyNamesToClassNames classNamesToIds propertyId = do+ rawPropertyName <- getPropertyName propertyIdsToNames propertyId+ let propertyName = normalizeName rawPropertyName+ className <- getClassName propertyNamesToClassNames propertyName+ classId <- getClassId classNamesToIds className+ pure (classId, className)+++getPropertyName :: (Monad m) => IntMap.IntMap StrictText.Text -> Int -> m StrictText.Text+getPropertyName propertyNames propertyId = do+ case IntMap.lookup propertyId propertyNames of+ Nothing -> do+ fail ("Could not find name for property " ++ show propertyId)+ Just propertyName -> do+ pure propertyName+++normalizeName :: StrictText.Text -> StrictText.Text+normalizeName name = name+ & StrictText.unpack+ & replace "_[0-9]+$" ""+ & replace "^[A-Z_a-z]+[.]TheWorld:" "TheWorld:"+ & StrictText.pack+++replace :: String -> String -> String -> String+replace pattern replacement input =+ Regex.subRegex (Regex.mkRegex pattern) input replacement+++getClassName :: (Monad m) => Map.Map StrictText.Text StrictText.Text -> StrictText.Text -> m StrictText.Text+getClassName classNames propertyName = do+ case Map.lookup propertyName classNames of+ Nothing -> do+ fail ("Could not find class for property " ++ show propertyName)+ Just className -> do+ pure className+++getClassId :: (Monad m) => Map.Map StrictText.Text Int -> StrictText.Text -> m Int+getClassId classIds className = do+ case Map.lookup className classIds of+ Nothing -> do+ fail ("Could not find ID for class " ++ show className)+ Just classId -> do+ pure classId
+ library/Octane/Utility/Embed.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE FlexibleContexts #-}++-- | These helper functions are usually used with 'Data.FileEmbed.embedFile'.+module Octane.Utility.Embed (decodeBimap, decodeMap, decodeSet) where++import Data.Function ((&))++import qualified Data.Aeson as Aeson+import qualified Data.Bimap as Bimap+import qualified Data.ByteString as StrictBytes+import qualified Data.Map.Strict as Map+import qualified Data.Maybe as Maybe+import qualified Data.Set as Set+++-- | Decodes some bytes into a bidirection map. The bytes are assumed to be a+-- JSON object mapping values to keys. That means the resulting bimap is+-- 'Bimap.twist'ed from what you might expect.+--+-- >>> decodeBimap "{ \"value\": \"key\" }" :: Bimap.Bimap String String+-- fromList [("key","value")]+decodeBimap+ :: (Aeson.FromJSON (Map.Map b a), Ord a, Ord b)+ => StrictBytes.ByteString+ -> Bimap.Bimap a b+decodeBimap bytes = bytes+ & Aeson.decodeStrict+ & Maybe.fromMaybe Map.empty+ & Map.toList+ & Bimap.fromList+ & Bimap.twist+++-- | Decodes some bytes into a map. The bytes are assumed to be a JSON object+-- mapping keys to values.+--+-- >>> decodeMap "{ \"key\": \"value\" }" :: Map.Map String String+-- fromList [("key","value")]+decodeMap+ :: (Aeson.FromJSON (Map.Map a b))+ => StrictBytes.ByteString+ -> Map.Map a b+decodeMap bytes = bytes+ & Aeson.decodeStrict+ & Maybe.fromMaybe Map.empty+++-- | Decodes some bytes into a set. The bytes are assumed to be a JSON array.+--+-- >>> decodeSet "[\"element\"]" :: Set.Set String+-- fromList ["element"]+decodeSet+ :: (Aeson.FromJSON a, Ord a)+ => StrictBytes.ByteString+ -> Set.Set a+decodeSet bytes = bytes+ & Aeson.decodeStrict+ & Maybe.fromMaybe Set.empty
library/Octane/Utility/Endian.hs view
@@ -12,11 +12,17 @@ -- | Reverses all the bits in each lazy byte.+--+-- >>> reverseBitsInLazyBytes "\x01"+-- "\128" reverseBitsInLazyBytes :: LazyBytes.ByteString -> LazyBytes.ByteString reverseBitsInLazyBytes bytes = LazyBytes.map reverseBits bytes -- | Reverses all the bits in each strict byte.+--+-- >>> reverseBitsInStrictBytes "\x01"+-- "\128" reverseBitsInStrictBytes :: StrictBytes.ByteString -> StrictBytes.ByteString reverseBitsInStrictBytes bytes = StrictBytes.map reverseBits bytes
library/Octane/Utility/Parser.hs view
@@ -12,8 +12,6 @@ import qualified Data.Binary.Bits.Get as Bits import qualified Data.Binary.Get as Binary import qualified Data.Bits as Bits-import qualified Data.ByteString as StrictBytes-import qualified Data.ByteString.Lazy as LazyBytes import qualified Data.IntMap.Strict as IntMap import qualified Data.Map.Strict as Map import qualified Data.Set as Set@@ -44,7 +42,6 @@ import qualified Octane.Type.Word64 as Word64 import qualified Octane.Type.Word8 as Word8 import qualified Octane.Utility.ClassPropertyMap as CPM-import qualified Octane.Utility.Endian as Endian import qualified Text.Printf as Printf @@ -163,7 +160,7 @@ objectName <- case context & contextObjectMap & IntMap.lookup (Int32.fromInt32 objectId) of Nothing -> fail ("could not find object name for id " ++ show objectId) Just x -> pure x- (classId, className) <- case CPM.getClass (contextObjectMap context) Data.objectToClass (contextClassMap context) (Int32.fromInt32 objectId) of+ (classId, className) <- case CPM.getClass (contextObjectMap context) Data.classes (contextClassMap context) (Int32.fromInt32 objectId) of Nothing -> fail ("could not find class for object id " ++ show objectId) Just x -> pure x classInit <- getInitialization className@@ -195,7 +192,7 @@ -> Bits.BitGet (Context, Replication.Replication) getExistingReplication context actorId = do thing <- case context & contextThings & IntMap.lookup actorId of- Nothing -> fail ("could not find thing for actor id " ++ show actorId)+ Nothing -> fail ("could not find thing for existing actor " ++ show actorId) Just x -> pure x props <- getProps context thing pure (context, Replication.Replication@@ -213,7 +210,7 @@ -> Bits.BitGet (Context, Replication.Replication) getClosedReplication context actorId = do thing <- case context & contextThings & IntMap.lookup actorId of- Nothing -> fail ("could not find thing for actor id " ++ show actorId)+ Nothing -> fail ("could not find thing for closed actor " ++ show actorId) Just x -> pure x let newThings = context & contextThings & IntMap.delete actorId let newContext = context { contextThings = newThings }@@ -266,40 +263,35 @@ getPropValue :: Context -> StrictText.Text -> Bits.BitGet Value.Value-getPropValue context name = case Map.lookup name (propertyNameToGet context) of- Nothing -> fail ("don't know how to read property " ++ show name)- Just get -> get---propertyNameToGet :: Context -> Map.Map StrictText.Text (Bits.BitGet Value.Value)-propertyNameToGet context =- [ (Data.booleanProperties, getBooleanProperty)- , (Data.byteProperties, getByteProperty)- , (Data.camSettingsProperties, getCamSettingsProperty)- , (Data.demolishProperties, getDemolishProperty)- , (Data.enumProperties, getEnumProperty)- , (Data.explosionProperties, getExplosionProperty)- , (Data.flaggedIntProperties, getFlaggedIntProperty)- , (Data.floatProperties, getFloatProperty)- , (Data.gameModeProperties, getGameModeProperty)- , (Data.intProperties, getIntProperty)- , (Data.loadoutOnlineProperties, getLoadoutOnlineProperty)- , (Data.loadoutProperties, getLoadoutProperty)- , (Data.locationProperties, getLocationProperty)- , (Data.musicStingerProperties, getMusicStingerProperty)- , (Data.pickupProperties, getPickupProperty)- , (Data.privateMatchSettingsProperties, getPrivateMatchSettingsProperty)- , (Data.qWordProperties, getQWordProperty)- , (Data.relativeRotationProperties, getRelativeRotationProperty)- , (Data.reservationProperties, getReservationProperty context)- , (Data.rigidBodyStateProperties, getRigidBodyStateProperty)- , (Data.stringProperties, getStringProperty)- , (Data.teamPaintProperties, getTeamPaintProperty)- , (Data.uniqueIdProperties, getUniqueIdProperty)- , (Set.fromList [StrictText.pack "TAGame.PRI_TA:PartyLeader"], getPartyLeaderProperty)- ]- & concatMap (\ (ks, v) -> ks & Set.toList & map (\ k -> (k, v)))- & Map.fromList+getPropValue context name = case Map.lookup name Data.properties of+ Just property -> case StrictText.unpack property of+ "boolean" -> getBooleanProperty+ "byte" -> getByteProperty+ "cam_settings" -> getCamSettingsProperty+ "demolish" -> getDemolishProperty+ "enum" -> getEnumProperty+ "explosion" -> getExplosionProperty+ "flagged_int" -> getFlaggedIntProperty+ "float" -> getFloatProperty+ "game_mode" -> getGameModeProperty+ "int" -> getIntProperty+ "loadout_online" -> getLoadoutOnlineProperty+ "loadout" -> getLoadoutProperty+ "location" -> getLocationProperty+ "music_stinger" -> getMusicStingerProperty+ "party_leader" -> getPartyLeaderProperty+ "pickup" -> getPickupProperty+ "private_match_settings" -> getPrivateMatchSettingsProperty+ "qword" -> getQWordProperty+ "relative_rotation" -> getRelativeRotationProperty+ "reservation" -> getReservationProperty context+ "rigid_body_state" -> getRigidBodyStateProperty+ "string" -> getStringProperty+ "team_paint" -> getTeamPaintProperty+ "unique_id" -> getUniqueIdProperty+ _ -> fail ("Don't know how to read property type " ++ show property ++ " for " ++ show name)+ Nothing -> do+ fail ("Don't know how to read property " ++ show name) getBooleanProperty :: Bits.BitGet Value.Value@@ -382,24 +374,14 @@ getLoadoutOnlineProperty :: Bits.BitGet Value.Value getLoadoutOnlineProperty = do- version <- getWord32- x <- getWord32- y <- getWord32- z <- if version >= 12- then do- value <- getWord8-- -- After the Neo Tokyo update, online loadouts could have this- -- ridiculously high "version". I think it means the player is- -- using an item with an unusual color.- Monad.when (version == 0x0100000c) (do- unknown <- Bits.getWord64be 37- Monad.when (unknown /= 0) (do- fail (Printf.printf "Read 37 online loadout bits and they weren't all 0! 0b%037b" unknown)))-- pure (Just value)- else pure Nothing- pure (Value.VLoadoutOnline version x y z)+ size <- getWord8+ values <- Monad.replicateM (size & Word8.unpack & fromIntegral) (do+ innerSize <- getWord8+ Monad.replicateM (innerSize & Word8.unpack & fromIntegral) (do+ x <- getWord32+ y <- getInt 27+ pure (x, y)))+ pure (Value.VLoadoutOnline values) getLoadoutProperty :: Bits.BitGet Value.Value@@ -537,7 +519,7 @@ getPartyLeaderProperty = do systemId <- getSystemId (remoteId, localId) <- if systemId == 0- then pure (RemoteId.SplitscreenId Nothing, Nothing)+ then pure (RemoteId.RemoteSplitscreenId (RemoteId.SplitscreenId Nothing), Nothing) else do remoteId <- getRemoteId systemId localId <- getLocalId@@ -546,11 +528,11 @@ getFloat32 :: Bits.BitGet Float32.Float32-getFloat32 = BinaryBit.getBits unimportant+getFloat32 = BinaryBit.getBits 0 getText :: Bits.BitGet Text.Text-getText = BinaryBit.getBits unimportant+getText = BinaryBit.getBits 0 getUniqueId :: Bits.BitGet (Word8.Word8, RemoteId.RemoteId, Maybe Word8.Word8)@@ -568,32 +550,17 @@ getRemoteId :: Word8.Word8 -> Bits.BitGet RemoteId.RemoteId getRemoteId systemId = case systemId of 0 -> do- remoteId <- Bits.getByteString 3- if StrictBytes.all (\ byte -> byte == 0) remoteId- then 0 & Just & RemoteId.SplitscreenId & pure- else fail ("unexpected splitscreen id " ++ show remoteId)+ splitscreenId <- BinaryBit.getBits 0+ pure (RemoteId.RemoteSplitscreenId splitscreenId) 1 -> do- bytes <- Bits.getByteString 8- let remoteId = Binary.runGet- Binary.getWord64le- (bytes & LazyBytes.fromStrict & Endian.reverseBitsInLazyBytes)- remoteId & Word64.toWord64 & RemoteId.SteamId & pure+ steamId <- BinaryBit.getBits 0+ pure (RemoteId.RemoteSteamId steamId) 2 -> do- bytes <- Bits.getByteString 32- let remoteId = bytes- & LazyBytes.fromStrict- & Endian.reverseBitsInLazyBytes- & LazyBytes.unpack- & concatMap (\ b -> Printf.printf "%02x" b)- & StrictText.pack- & Text.Text- remoteId & RemoteId.PlayStationId & pure+ playStationId <- BinaryBit.getBits 0+ pure (RemoteId.RemotePlayStationId playStationId) 4 -> do- bytes <- Bits.getByteString 8- let remoteId = Binary.runGet- Binary.getWord64le- (bytes & LazyBytes.fromStrict & Endian.reverseBitsInLazyBytes)- remoteId & Word64.toWord64 & RemoteId.XboxId & pure+ xboxId <- BinaryBit.getBits 0+ pure (RemoteId.RemoteXboxId xboxId) _ -> fail ("unknown system id " ++ show systemId) @@ -721,13 +688,13 @@ getInitialization :: StrictText.Text -> Bits.BitGet Initialization.Initialization getInitialization className = do location <-- if Set.member className Data.locationClasses+ if Set.member className Data.classesWithLocation then do vector <- getVector pure (Just vector) else pure Nothing rotation <-- if Set.member className Data.rotationClasses+ if Set.member className Data.classesWithRotation then do vector <- getVectorBytewise pure (Just vector)@@ -773,23 +740,23 @@ getInt32 :: Bits.BitGet Int32.Int32-getInt32 = BinaryBit.getBits unimportant+getInt32 = BinaryBit.getBits 0 getInt8 :: Bits.BitGet Int8.Int8-getInt8 = BinaryBit.getBits unimportant+getInt8 = BinaryBit.getBits 0 getWord64 :: Bits.BitGet Word64.Word64-getWord64 = BinaryBit.getBits unimportant+getWord64 = BinaryBit.getBits 0 getWord32 :: Bits.BitGet Word32.Word32-getWord32 = BinaryBit.getBits unimportant+getWord32 = BinaryBit.getBits 0 getWord8 :: Bits.BitGet Word8.Word8-getWord8 = BinaryBit.getBits unimportant+getWord8 = BinaryBit.getBits 0 getActorId :: Bits.BitGet Int@@ -805,10 +772,4 @@ getBool :: Bits.BitGet Boolean.Boolean-getBool = BinaryBit.getBits unimportant----- | The 'getBits' function from "Data.Binary.Bits" requires a size parameter.--- None of Octane's instances use it.-unimportant :: Int-unimportant = 0+getBool = BinaryBit.getBits 0
octane.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack name: octane-version: 0.12.0+version: 0.13.0 synopsis: Parse Rocket League replays. description: Octane parses Rocket League replays. category: Game@@ -17,6 +17,12 @@ extra-source-files: CHANGELOG.markdown+ data/classes-with-location.json+ data/classes-with-rotation.json+ data/classes.json+ data/game-modes.json+ data/products.json+ data/properties.json package.yaml README.markdown stack.yaml@@ -39,26 +45,16 @@ , containers ==0.5.* , data-binary-ieee754 ==0.4.* , deepseq ==1.4.*+ , file-embed ==0.0.* , http-client ==0.4.* , http-client-tls ==0.2.*+ , regex-compat ==0.95.* , text ==1.2.* , unordered-containers ==0.2.* , vector ==0.11.* exposed-modules: Octane Octane.Data- Octane.Data.Antennas- Octane.Data.Bodies- Octane.Data.Bots- Octane.Data.Classes- Octane.Data.Decals- Octane.Data.Finishes- Octane.Data.GameModes- Octane.Data.Logos- Octane.Data.Properties- Octane.Data.RocketTrails- Octane.Data.Toppers- Octane.Data.Wheels Octane.Main Octane.Type Octane.Type.Boolean@@ -95,6 +91,7 @@ Octane.Utility Octane.Utility.ClassPropertyMap Octane.Utility.CRC+ Octane.Utility.Embed Octane.Utility.Endian Octane.Utility.Optimizer Octane.Utility.Parser
package.yaml view
@@ -25,6 +25,7 @@ source-dirs: executable extra-source-files: - CHANGELOG.markdown+- data/*.json - package.yaml - README.markdown - stack.yaml@@ -41,8 +42,10 @@ - containers ==0.5.* - data-binary-ieee754 ==0.4.* - deepseq ==1.4.*+ - file-embed ==0.0.* - http-client ==0.4.* - http-client-tls ==0.2.*+ - regex-compat ==0.95.* - text ==1.2.* - unordered-containers ==0.2.* - vector ==0.11.*@@ -76,4 +79,4 @@ - -with-rtsopts=-N main: Main.hs source-dirs: test-suite-version: '0.12.0'+version: '0.13.0'