1
Fork 0
mirror of https://github.com/Steffo99/lihzahrd.git synced 2024-11-21 15:44:24 +00:00

Process unknown data

This commit is contained in:
Steffo 2023-03-06 02:21:06 +01:00
parent 66d0e221e1
commit d451fd3731
4 changed files with 231 additions and 16 deletions

View file

@ -22,6 +22,12 @@ It _will_ take a while to process: a small Terraria world contains more than 5 m
Once you have a `World` object, you can use all data present in the save file by accessing [its attributes](http://gh.steffo.eu/lihzahrd/html/world.html).
> **Warning**
>
> Maliciously designed Terraria worlds can drain system resources, crash the interpreter, or possibly do more evil things!
>
> **Make sure you trust the worlds you are parsing!**
## Documentation
The documentation is available [here](https://gh.steffo.eu/lihzahrd/html/).

View file

@ -5143,6 +5143,181 @@ class ItemType(enum.IntEnum):
PRINCESS_64 = 5085
PAINTING_OF_A_LASS = 5086
DARK_SIDE_OF_THE_HOLLOW = 5087
BERNIES_BUTTON = 5088
GLOMMERS_FLOWER = 5089
DEERCLOPS_EYEBALL = 5090
MONSTER_MEAT = 5091
MONSTER_LASAGNA = 5092
FROGGLE_BUNWICH = 5093
TENTACLE_SPIKE = 5094
LUCY_THE_AXE = 5095
HAM_BAT = 5096
BAT_BAT = 5097
EYE_BONE = 5098
GARLAND = 5099
BONE_HELM = 5100
EYEBRELLA = 5101
GENTLEMANS_VEST = 5102
GENTLEMANS_TROUSERS = 5103
GENTLEMANS_BEARD = 5104
GENTLEMANS_LONG_BEARD = 5105
GENTLEMANS_MAGNIFICENT_BEARD = 5106
MAGILUMINESCENCE = 5107
DEERCLOPS_TROPHY = 5108
DEERCLOPS_MASK = 5109
DEERCLOPS_RELIC = 5110
TREASURE_BAG_DEERCLOPS = 5111
MUSIC_BOX_DEERCLOPS = 5112
RADIO_THING = 5113
ABIGAILS_FLOWER = 5114
FIRESTARTERS_SWEATER = 5115
FIRESTARTERS_SKIRT = 5116
PEW_MATIC_HORN = 5117
WEATHER_PAIN = 5118
HOUNDIUS_SHOOTIUS = 5119
DEER_THING = 5120
THE_GENTLEMAN_SCIENTIST = 5121
THE_FIRESTARTER = 5122
THE_BEREAVED = 5123
THE_STRONGMAN = 5124
FART_MINECART = 5125
HAND_OF_CREATION = 5126
VIOLET_MOSS = 5127
RAINBOW_MOSS = 5128
FLYMEAL = 5129
WOLF_MOUNT_ITEM = 5130
RESPLENDENT_DESSERT = 5131
STINKBUG = 5132
STINKBUG_CAGE = 5133
CLENTAMINATOR_2 = 5134
VENOM_DART_TRAP = 5135
VULKELF_EAR = 5136
STINKBUG_HOUSING_BLOCKER = 5137
STINKBUG_HOUSING_BLOCKER_ECHO = 5138
FISHING_BOBBER = 5139
FISHING_BOBBER_GLOWING_STAR = 5140
FISHING_BOBBER_GLOWING_LAVA = 5141
FISHING_BOBBER_GLOWING_KRYPTON = 5142
FISHING_BOBBER_GLOWING_XENON = 5143
FISHING_BOBBER_GLOWING_ARGON = 5144
FISHING_BOBBER_GLOWING_VIOLET = 5145
FISHING_BOBBER_GLOWING_RAINBOW = 5146
WANDOF_FROSTING = 5147
CORAL_BATHTUB = 5148
CORAL_BED = 5149
CORAL_BOOKCASE = 5150
CORAL_DRESSER = 5151
CORAL_CANDELABRA = 5152
CORAL_CANDLE = 5153
CORAL_CHAIR = 5154
CORAL_CHANDELIER = 5155
CORAL_CHEST = 5156
CORAL_CLOCK = 5157
CORAL_DOOR = 5158
CORAL_LAMP = 5159
CORAL_LANTERN = 5160
CORAL_PIANO = 5161
CORAL_PLATFORM = 5162
CORAL_SINK = 5163
CORAL_SOFA = 5164
CORAL_TABLE = 5165
CORAL_WORKBENCH = 5166
FAKE_CORAL_CHEST = 5167
CORAL_TOILET = 5168
BALLOON_BATHTUB = 5169
BALLOON_BED = 5170
BALLOON_BOOKCASE = 5171
BALLOON_DRESSER = 5172
BALLOON_CANDELABRA = 5173
BALLOON_CANDLE = 5174
BALLOON_CHAIR = 5175
BALLOON_CHANDELIER = 5176
BALLOON_CHEST = 5177
BALLOON_CLOCK = 5178
BALLOON_DOOR = 5179
BALLOON_LAMP = 5180
BALLOON_LANTERN = 5181
BALLOON_PIANO = 5182
BALLOON_PLATFORM = 5183
BALLOON_SINK = 5184
BALLOON_SOFA = 5185
BALLOON_TABLE = 5186
BALLOON_WORKBENCH = 5187
FAKE_BALLOON_CHEST = 5188
BALLOON_TOILET = 5189
ASH_WOOD_BATHTUB = 5190
ASH_WOOD_BED = 5191
ASH_WOOD_BOOKCASE = 5192
ASH_WOOD_DRESSER = 5193
ASH_WOOD_CANDELABRA = 5194
ASH_WOOD_CANDLE = 5195
ASH_WOOD_CHAIR = 5196
ASH_WOOD_CHANDELIER = 5197
ASH_WOOD_CHEST = 5198
ASH_WOOD_CLOCK = 5199
ASH_WOOD_DOOR = 5200
ASH_WOOD_LAMP = 5201
ASH_WOOD_LANTERN = 5202
ASH_WOOD_PIANO = 5203
ASH_WOOD_PLATFORM = 5204
ASH_WOOD_SINK = 5205
ASH_WOOD_SOFA = 5206
ASH_WOOD_TABLE = 5207
ASH_WOOD_WORKBENCH = 5208
FAKE_ASH_WOOD_CHEST = 5209
ASH_WOOD_TOILET = 5210
BIOME_SIGHT_POTION = 5211
SCARLET_MACAW = 5212
SCARLET_MACAW_CAGE = 5213
ASH_GRASS_SEEDS = 5214
ASH_WOOD = 5215
ASH_WOOD_WALL = 5216
ASH_WOOD_FENCE = 5217
OUTCAST = 5218
FAIRY_GUIDES = 5219
AHORRIBLE_NIGHTFOR_ALCHEMY = 5220
MORNING_HUNT = 5221
SUSPICIOUSLY_SPARKLY = 5222
REQUIEM = 5223
CAT_SWORD = 5224
KARGOHS_SUMMON = 5225
HIGH_PITCH = 5226
AMACHINEFOR_TERRARIANS = 5227
TERRA_BLADE_CHRONICLES = 5228
BENNY_WARHOL = 5229
LIZARD_KING = 5230
MY_SON = 5231
DUALITY = 5232
PARSEC_PALS = 5233
REMNANTSOF_DEVOTION = 5234
NOT_SO_LOST_IN_PARADISE = 5235
OCULAR_RESONANCE = 5236
WINGSOF_EVIL = 5237
CONSTELLATION = 5238
EYEZORHEAD = 5239
DREADOFTHE_RED_SEA = 5240
DO_NOT_EATTHE_VILE_MUSHROOM = 5241
YUUMA_THE_BLUE_TIGER = 5242
MOONMANAND_COMPANY = 5243
SUNSHINEOF_ISRAPONY = 5244
PURITY = 5245
SUFFICIENTLY_ADVANCED = 5246
STRANGE_GROWTH = 5247
HAPPY_LITTLE_TREE = 5248
STRANGE_DEAD_FELLOWS = 5249
SECRETS = 5250
THUNDERBOLT = 5251
CRUSTOGRAPHY = 5252
THE_WEREWOLF = 5253
BLESSINGFROM_THE_HEAVENS = 5254
LOVEISINTHE_TRASH_SLOT = 5255
FANGS = 5256
HAILTOTHE_KING = 5257
SEE_THE_WORLD_FOR_WHAT_IT_IS = 5258
WHAT_LURKS_BELOW = 5259
THIS_IS_GETTING_OUT_OF_HAND = 5260
BUDDIES = 5261
MIDNIGHT_SUN = 5262
COUCH_GAG = 5263
SILENT_FISH = 5264
THE_DUKE = 5265

View file

@ -2,7 +2,7 @@ class Time:
"""Game time related information."""
def __init__(
self, current: float, is_daytime: bool, moon_phase: int, sundial_cooldown: int, fast_forward_time: bool
self, current: float, is_daytime: bool, moon_phase: int, sundial_cooldown: int, sundial_is_running: bool, moondial_cooldown: int, moondial_is_running: bool
):
self.current: float = current
"""The current game time."""
@ -16,10 +16,17 @@ class Time:
self.sundial_cooldown: int = sundial_cooldown
"""The number of days the Enchanted Sundial can't be used for."""
self.fast_forward_time: bool = fast_forward_time
self.sundial_is_running: bool = sundial_is_running
"""Whether the Enchanted Sundial is currently fast-forwarding time."""
self.moondial_cooldown: int = sundial_cooldown
"""The number of days the Enchanted Moondial can't be used for."""
self.moondial_is_running: bool = sundial_is_running
"""Whether the Enchanted Moondial is currently fast-forwarding time."""
def __repr__(self):
return (
f"WorldTime(current={self.current}, is_daytime={self.is_daytime}, moon_phase={self.moon_phase},"
f" sundial_cooldown={self.sundial_cooldown}, fast_forward_time={self.fast_forward_time})"
f" sundial_cooldown={self.sundial_cooldown}, fast_forward_time={self.sundial_is_running})"
)

View file

@ -1,5 +1,6 @@
import uuid
import math
import sys
from typing import *
from .fileutils import *
from .enums import *
@ -64,6 +65,7 @@ class World:
journey_powers: JourneyPowers,
chests: List[Chest],
signs: List[Sign],
shimmered_npcs: List[int],
npcs: List[NPC],
mobs: List[Mob],
tile_entities: List[TileEntity],
@ -201,6 +203,9 @@ class World:
self.signs: List[Sign] = signs
"""A list of all non-empty signs in the world."""
self.shimmered_npcs: List[int] = shimmered_npcs
"""A list of the ids of the NPCs that have been shimmered."""
self.npcs: List[NPC] = npcs
"""A list of all the NPCs currently living in the world, including the Old Man."""
@ -410,11 +415,18 @@ class World:
# File header
version = Version(f.int4())
relogic = f.string(7) # TODO: this can appearently be "xindong"?
if relogic != "relogic":
raise ValueError("World file is missing the 'relogic' magic string", relogic)
savefile_type = f.uint1()
supported_versions = (Version("1.4.4.9"), Version("1.4.4.9"))
if version not in supported_versions or relogic != "relogic" or savefile_type != 2:
raise NotImplementedError("This parser can only read Terraria 1.4.4.9 save files.")
if savefile_type != 2:
raise NotImplementedError("World file uses an unknown savefile type", savefile_type)
supported_versions = (Version("1.4.4.9"),)
if version not in supported_versions:
raise NotImplementedError("World file has been created with a unsupported version of Terraria", version)
revision = f.uint4()
is_favorite = f.uint8() != 0
@ -573,14 +585,7 @@ class World:
for mob_id in range(mob_types_count):
mob_kills[mob_id] = f.int4()
fast_forward_time = f.bool()
time = Time(
current=current_time,
is_daytime=is_daytime,
moon_phase=moon_phase,
sundial_cooldown=sundial_cooldown,
fast_forward_time=fast_forward_time,
)
sundial_is_running = f.bool()
defeated_duke_fishron = f.bool()
defeated_martian_madness = f.bool()
@ -714,8 +719,6 @@ class World:
deerclops=defeated_deerclops,
)
defeated_deerclops = f.bool()
saved_slime_nerdy = f.bool()
saved_merchant = f.bool()
saved_demolitionist = f.bool()
@ -765,6 +768,19 @@ class World:
slime_squire=saved_slime_squire,
)
moondial_is_running = f.bool()
moondial_cooldown = f.uint1()
time = Time(
current=current_time,
is_daytime=is_daytime,
moon_phase=moon_phase,
sundial_cooldown=sundial_cooldown,
sundial_is_running=sundial_is_running,
moondial_cooldown=moondial_cooldown,
moondial_is_running=moondial_is_running,
)
unknown_world_header_data = f.read_until(pointers.world_tiles)
# Tiles
@ -814,6 +830,11 @@ class World:
npcs = []
mobs = []
shimmered_npcs_count = f.int4()
shimmered_npcs = []
for _ in range(shimmered_npcs_count):
shimmered_npcs.append(f.int4())
while f.bool():
npc_type = EntityType(f.int4())
npc_name = f.string()
@ -1013,6 +1034,7 @@ class World:
tiles=tm,
chests=chests,
signs=signs,
shimmered_npcs=shimmered_npcs,
npcs=npcs,
mobs=mobs,
tile_entities=tile_entities,
@ -1049,3 +1071,8 @@ class World:
f.file.close()
return world
if __name__ == "__main__":
world = World.create_from_file(sys.argv[1])
breakpoint()