Created
February 6, 2019 17:17
-
-
Save vfig/94b353fa41e5e38ac912df91ffbb07e8 to your computer and use it in GitHub Desktop.
Sunless Skies qualities/events parser (rough and ready)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Use Unity Asset Extractor to save the qualities and events assets to "qualities.dat" and "events.dat" respectively. | |
# Then run this script to explore the data. | |
# | |
# Needs Python 3.6 | |
import struct, textwrap | |
# For indenting a string: | |
def indent(s): | |
return '\n'.join((' ' + l) for l in str(s).splitlines()) | |
# For saner hexifying | |
def hexify(b): | |
s = b.hex() | |
return " ".join([s[i:i+2] for i in range(0, len(s), 2)]) | |
#----------------------------- | |
class BinaryReader: | |
def __init__(self, data): | |
self.data = data[:] | |
self.offset = 0 | |
def debug_dump(self, description=''): | |
size = 16 | |
pre_ofs = max(0, self.offset-size) | |
post_ofs = min(self.offset+size, len(self.data)) | |
b = self.data[pre_ofs:post_ofs] | |
print() | |
print(f":: {description} @ 0x{self.offset:08x}:") | |
print(hexify(b)) | |
print((" " * (self.offset - pre_ofs)) + "^^ ") | |
def Seek(self, offset): | |
self.offset = offset | |
def _read_single_fmt(fmt, name=''): | |
def _read(self): | |
d_len = struct.calcsize(fmt) | |
d = struct.unpack_from(fmt, self.data, self.offset) | |
self.offset += d_len | |
return d[0] | |
if name: | |
_read.__name__ = ('Read' + name) | |
return _read | |
ReadUint8 = _read_single_fmt('@B', 'Uint8') | |
ReadUint16 = _read_single_fmt('@H', 'Uint16') | |
ReadUint32 = _read_single_fmt('@L', 'Uint32') | |
ReadUint64 = _read_single_fmt('@Q', 'Uint64') | |
ReadInt8 = _read_single_fmt('@b', 'Int8') | |
ReadInt16 = _read_single_fmt('@h', 'Int16') | |
ReadInt32 = _read_single_fmt('@l', 'Int32') | |
ReadInt64 = _read_single_fmt('@q', 'Int64') | |
ReadSingle = _read_single_fmt('@f', 'Single') | |
ReadDouble = _read_single_fmt('@d', 'Double') | |
def ReadBoolean(self): | |
return (self.ReadUint8() != 0) | |
def ReadString(self): | |
_start = self.offset | |
d_len = self._ReadVarInt() | |
d = self._ReadBytes(d_len) | |
try: | |
return d.decode('utf8') | |
except UnicodeDecodeError: | |
# For wrapping printed output | |
wrapper = textwrap.TextWrapper() | |
wrapper.width = 80 | |
wrapper.initial_indent = ' ' | |
wrapper.subsequent_indent = ' ' | |
wrapper.break_on_hyphens = False | |
print(f"Cannot decode string at offset 0x{_start:x}:") | |
print(wrapper.fill(hexify(d))) | |
raise | |
def _ReadVarInt(self): | |
accum = 0 | |
shift = 0 | |
while True: | |
b = self.ReadUint8() | |
last_byte = ((b & 0x80) == 0) | |
accum |= ((b & 0x7F) << shift) | |
shift += 7 | |
if last_byte: | |
break | |
return accum | |
def _ReadBytes(self, n): | |
d_len = n | |
d = self.data[self.offset:self.offset+n] | |
self.offset += d_len | |
return d | |
class Area: | |
pass | |
class BinarySerializer_Area: | |
@classmethod | |
def Deserialize(cls, bs): | |
area = Area() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
area.Description = bs.ReadString() | |
if bs.ReadBoolean(): | |
area.ImageName = bs.ReadString() | |
if bs.ReadBoolean(): | |
area.World = BinarySerializer_World.Deserialize(bs) | |
area.MarketAccessPermitted = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
area.MoveMessage = bs.ReadString() | |
area.HideName = bs.ReadBoolean() | |
area.RandomPostcard = bs.ReadBoolean() | |
area.MapX = bs.ReadInt32() | |
area.MapY = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
area.UnlocksWithQuality = BinarySerializer_Quality.Deserialize(bs) | |
area.ShowOps = bs.ReadBoolean() | |
area.PremiumSubRequired = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
area.Name = bs.ReadString() | |
area.Id = bs.ReadInt32() | |
return area | |
@classmethod | |
def DeserializeCollection(cls, bs): | |
l = [] | |
num = bs.ReadInt32() | |
for i in range(num): | |
l.append(cls.Deserialize(bs)) | |
return l | |
class AspectQPossession: | |
pass | |
class BinarySerializer_AspectQPossession: | |
@classmethod | |
def Deserialize(cls, bs): | |
aspectQPossession = AspectQPossession() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
aspectQPossession.Quality = BinarySerializer_Quality.Deserialize(bs) | |
aspectQPossession.XP = bs.ReadInt32() | |
aspectQPossession.EffectiveLevelModifier = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
aspectQPossession.TargetQuality = BinarySerializer_Quality.Deserialize(bs) | |
if bs.ReadBoolean(): | |
aspectQPossession.TargetLevel = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
aspectQPossession.CompletionMessage = bs.ReadString() | |
aspectQPossession.Level = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
aspectQPossession.AssociatedQuality = BinarySerializer_Quality.Deserialize(bs) | |
aspectQPossession.Id = bs.ReadInt32() | |
return aspectQPossession | |
class Branch: | |
def __init__(self): | |
self.SuccessEvent = None | |
self.DefaultEvent = None | |
self.RareDefaultEvent = None | |
self.RareDefaultEventChance = 0 | |
self.RareSuccessEvent = None | |
self.RareSuccessEventChance = 0 | |
self.ParentEvent = None | |
self.QualitiesRequired = [] | |
self.Image = '' | |
self.Description = '' | |
self.OwnerName = '' | |
self.DateTimeCreated = 0 # DateTime | |
self.CurrencyCost = 0 | |
self.Archived = False | |
self.RenameQualityCategory = 0 | |
self.ButtonText = '' | |
self.Ordering = 0 | |
self.Act = None | |
self.ActionCost = 0 | |
self.Name = '' | |
self.Id = 0 | |
def __str__(self): | |
lines = [f"Branch {self.Id}: \"{self.Name}\""] | |
for r in self.QualitiesRequired: | |
lines.append(f" requires: {r}") | |
if self.DefaultEvent: | |
lines.append(f" Default:\n{indent(self.DefaultEvent)}") | |
if self.RareDefaultEvent: | |
lines.append(f" RareDefault ({self.RareDefaultEventChance}):\n{indent(self.RareDefaultEvent)}") | |
if self.SuccessEvent: | |
lines.append(f" Success:\n{indent(self.SuccessEvent)}") | |
if self.RareSuccessEvent: | |
lines.append(f" RareSuccess ({self.RareSuccessEventChance}):\n{indent(self.RareSuccessEvent)}") | |
return '\n'.join(lines) | |
def __repr__(self): | |
return str(self) | |
class BinarySerializer_Branch: | |
@classmethod | |
def Deserialize(cls, bs): | |
branch = Branch() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
branch.SuccessEvent = BinarySerializer_Event.Deserialize(bs) | |
if bs.ReadBoolean(): | |
branch.DefaultEvent = BinarySerializer_Event.Deserialize(bs) | |
if bs.ReadBoolean(): | |
branch.RareDefaultEvent = BinarySerializer_Event.Deserialize(bs) | |
branch.RareDefaultEventChance = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
branch.RareSuccessEvent = BinarySerializer_Event.Deserialize(bs) | |
branch.RareSuccessEventChance = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
branch.ParentEvent = BinarySerializer_Event.Deserialize(bs) | |
if bs.ReadBoolean(): | |
branch.QualitiesRequired = [] | |
num = bs.ReadInt32() | |
for i in range(num): | |
branch.QualitiesRequired.append(BinarySerializer_BranchQRequirement.Deserialize(bs)) | |
if bs.ReadBoolean(): | |
branch.Image = bs.ReadString() | |
if bs.ReadBoolean(): | |
branch.Description = bs.ReadString() | |
if bs.ReadBoolean(): | |
branch.OwnerName = bs.ReadString() | |
branch.DateTimeCreated = BinarySerializer_DateTime.Deserialize(bs) | |
branch.CurrencyCost = bs.ReadInt32() | |
branch.Archived = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
branch.RenameQualityCategory = BinarySerializer_Category.Deserialize(bs) | |
if bs.ReadBoolean(): | |
branch.ButtonText = bs.ReadString() | |
branch.Ordering = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
branch.Act = BinarySerializer_Act.Deserialize(bs) | |
branch.ActionCost = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
branch.Name = bs.ReadString() | |
branch.Id = bs.ReadInt32() | |
return branch | |
class BranchQRequirement: | |
def __str__(self): | |
Quality = getattr(self, 'AssociatedQuality', None) | |
QualityId = getattr(Quality, 'Id', 0) | |
MinLevel = getattr(self, 'MinLevel', -1) | |
MaxLevel = getattr(self, 'MaxLevel', -1) | |
MinAdvanced = getattr(self, 'MinAdvanced', -1) | |
MaxAdvanced = getattr(self, 'MaxAdvanced', -1) | |
return f"Requires Quality {QualityId}, Min: {MinLevel}, Max: {MaxLevel}, MinAdvanced: {MinAdvanced}, MaxAdvanced: {MaxAdvanced}" | |
def __repr__(self): | |
return str(self) | |
class BinarySerializer_BranchQRequirement: | |
@classmethod | |
def Deserialize(cls, bs): | |
branchQRequirement = BranchQRequirement() | |
if not bs.ReadBoolean(): | |
return null | |
if bs.ReadBoolean(): | |
branchQRequirement.DifficultyLevel = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
branchQRequirement.DifficultyAdvanced = bs.ReadString() | |
branchQRequirement.VisibleWhenRequirementFailed = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
branchQRequirement.CustomLockedMessage = bs.ReadString() | |
if bs.ReadBoolean(): | |
branchQRequirement.CustomUnlockedMessage = bs.ReadString() | |
branchQRequirement.IsCostRequirement = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
branchQRequirement.MinLevel = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
branchQRequirement.MaxLevel = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
branchQRequirement.MinAdvanced = bs.ReadString() | |
if bs.ReadBoolean(): | |
branchQRequirement.MaxAdvanced = bs.ReadString() | |
if bs.ReadBoolean(): | |
branchQRequirement.AssociatedQuality = BinarySerializer_Quality.Deserialize(bs) | |
branchQRequirement.Id = bs.ReadInt32() | |
return branchQRequirement | |
class BinarySerializer_Category: | |
@classmethod | |
def Deserialize(cls, bs): | |
category = 0 # Category.Unspecified | |
return bs.ReadInt32() | |
class BinarySerializer_DateTime: | |
@classmethod | |
def Deserialize(cls, bs): | |
return 0 # HACK: I don't know why this is not implemented, but it appears to be the case! | |
class Deck: | |
pass | |
class BinarySerializer_Deck: | |
@classmethod | |
def Deserialize(cls, bs): | |
deck = Deck() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
deck.World = BinarySerializer_World.Deserialize(bs) | |
if bs.ReadBoolean(): | |
deck.Name = bs.ReadString() | |
if bs.ReadBoolean(): | |
deck.ImageName = bs.ReadString() | |
deck.Ordering = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
deck.Description = bs.ReadString() | |
deck.Availability = BinarySerializer_Frequency.Deserialize(bs) | |
deck.DrawSize = bs.ReadInt32() | |
deck.MaxCards = bs.ReadInt32() | |
deck.Id = bs.ReadInt32() | |
return deck | |
class BinarySerializer_DifficultyTestType: | |
@classmethod | |
def Deserialize(self, bs): | |
difficultyTestType = 0 # DifficultyTestType.Broad | |
return bs.ReadInt32() | |
class Event: | |
def __init__(self): | |
self.Id = 0 # From Entity | |
self.Name = '' # from EntityWithName | |
self._moveToArea = None # Area | |
self._moveToDomicile = None # Domicile | |
self._switchToSetting = None # Setting | |
self._fatePointsChange = 0 | |
self._bootyValue = 0 | |
self.ChildBranches = [] | |
self.ParentBranch = None # Branch | |
self.QualitiesAffected = [] | |
self.QualitiesRequired = [] | |
self.Image = '' | |
self.SecondImage = '' | |
self.Description = '' | |
self.Tag = '' | |
self.ExoticEffects = '' | |
self.Note = '' | |
self.ChallengeLevel = 0 | |
self.UnclearedEditAt = None # DateTime? | |
self.LastEditedBy = None # User | |
self.Ordering = 0.0 | |
self.ShowAsMessage = False | |
self.LivingStory = None # LivingStory | |
self.LinkToEvent = None # Event | |
self.Deck = None # Deck | |
self.Category = 0 # EventCategory | |
self.LimitedToArea = None # Area | |
self.World = None # World | |
self.Transient = False | |
self.Stickiness = 0 | |
self.MoveToAreaId = 0 | |
self.LogInJournalAgainstQuality = None # Quality | |
self.Setting = None # Setting | |
self.Urgency = None # Urgency | |
self.OwnerName = '' | |
self.DateTimeCreated = 0 # DateTime | |
self.Distribution = 0 | |
self.Autofire = False | |
self.CanGoBack = False | |
def __str__(self): | |
lines = [f"[{self.Id}: {self.Name}]"] | |
for r in self.QualitiesRequired: | |
lines.append(f" requires: {r}") | |
for a in self.QualitiesAffected: | |
lines.append(f" affects: {a}") | |
if self.LinkToEvent: | |
lines.append(f" LINK TO: {self.LinkToEvent}") | |
for i, b in enumerate(self.ChildBranches): | |
lines.append(f"> {i}:\n{indent(b)}") | |
return '\n'.join(lines) | |
def __repr__(self): | |
return str(self) | |
class BinarySerializer_Event: | |
@classmethod | |
def Deserialize(cls, bs, debug=False): | |
if debug: bs.debug_dump('Event begins') | |
event = Event() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
event.ChildBranches = [] | |
num = bs.ReadInt32() | |
for i in range(num): | |
event.ChildBranches.append(BinarySerializer_Branch.Deserialize(bs)) | |
if bs.ReadBoolean(): | |
event.ParentBranch = BinarySerializer_Branch.Deserialize(bs) | |
if bs.ReadBoolean(): | |
event.QualitiesAffected = [] | |
num2 = bs.ReadInt32() | |
for j in range(num2): | |
event.QualitiesAffected.append(BinarySerializer_EventQEffect.Deserialize(bs)) | |
if bs.ReadBoolean(): | |
event.QualitiesRequired = [] | |
num3 = bs.ReadInt32() | |
for k in range(num3): | |
event.QualitiesRequired.append(BinarySerializer_EventQRequirement.Deserialize(bs)) | |
if bs.ReadBoolean(): | |
event.Image = bs.ReadString() | |
if bs.ReadBoolean(): | |
event.SecondImage = bs.ReadString() | |
if bs.ReadBoolean(): | |
event.Description = bs.ReadString() | |
if debug: print(f"Description: {event.Description}") | |
if bs.ReadBoolean(): | |
event.Tag = bs.ReadString() | |
if bs.ReadBoolean(): | |
event.ExoticEffects = bs.ReadString() | |
if bs.ReadBoolean(): | |
event.Note = bs.ReadString() | |
event.ChallengeLevel = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
event.UnclearedEditAt = BinarySerializer_DateTime.Deserialize(bs) | |
if bs.ReadBoolean(): | |
event.LastEditedBy = BinarySerializer_User.Deserialize(bs) | |
event.Ordering = bs.ReadSingle() | |
event.ShowAsMessage = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
event.LivingStory = BinarySerializer_LivingStory.Deserialize(bs) | |
if bs.ReadBoolean(): | |
event.LinkToEvent = cls.Deserialize(bs) | |
if bs.ReadBoolean(): | |
event.Deck = BinarySerializer_Deck.Deserialize(bs) | |
event.Category = BinarySerializer_EventCategory.Deserialize(bs) | |
if bs.ReadBoolean(): | |
event.LimitedToArea = BinarySerializer_Area.Deserialize(bs) | |
if bs.ReadBoolean(): | |
event.World = BinarySerializer_World.Deserialize(bs) | |
event.Transient = bs.ReadBoolean() | |
event.Stickiness = bs.ReadInt32() | |
event.MoveToAreaId = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
event.MoveToArea = BinarySerializer_Area.Deserialize(bs) | |
if bs.ReadBoolean(): | |
event.MoveToDomicile = BinarySerializer_Domicile.Deserialize(bs) | |
if bs.ReadBoolean(): | |
event.SwitchToSetting = BinarySerializer_Setting.Deserialize(bs) | |
event.FatePointsChange = bs.ReadInt32() | |
event.BootyValue = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
event.LogInJournalAgainstQuality = BinarySerializer_Quality.Deserialize(bs) | |
if bs.ReadBoolean(): | |
event.Setting = BinarySerializer_Setting.Deserialize(bs) | |
event.Urgency = BinarySerializer_Urgency.Deserialize(bs) | |
if bs.ReadBoolean(): | |
event.Teaser = bs.ReadString() | |
if bs.ReadBoolean(): | |
event.OwnerName = bs.ReadString() | |
if debug: print(f"OwnerName: {event.OwnerName}") | |
if debug: bs.debug_dump('Datetime here:') | |
event.DateTimeCreated = BinarySerializer_DateTime.Deserialize(bs) | |
event.Distribution = bs.ReadInt32() | |
event.Autofire = bs.ReadBoolean() | |
event.CanGoBack = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
event.Name = bs.ReadString() | |
event.Id = bs.ReadInt32() | |
if debug: print(f"----- Deserialized Event {event.Id}") | |
return event | |
@classmethod | |
def DeserializeCollection(cls, bs): | |
l = [] | |
num = bs.ReadInt32() | |
for i in range(num): | |
l.append(cls.Deserialize(bs)) | |
return l | |
class BinarySerializer_EventCategory: | |
@classmethod | |
def Deserialize(cls, bs): | |
eventCategory = 0 #EventCategory.Unspecialised | |
return bs.ReadInt32() | |
class EventQEffect: | |
def __init__(self): | |
self.Priority = 0 | |
self.ForceEquip = False | |
self.OnlyIfNoMoreThanAdvanced = '' | |
self.OnlyIfAtLeast = 0 | |
self.OnlyIfNoMoreThan = 0 | |
self.SetToExactlyAdvanced = '' | |
self.ChangeByAdvanced = '' | |
self.OnlyIfAtLeastAdvanced = '' | |
self.SetToExactly = 0 | |
self.TargetQuality = None | |
self.TargetLevel = 0 | |
self.CompletionMessage = '' | |
self.Level = 0 | |
self.AssociatedQuality = None | |
self.Id = 0 | |
def __str__(self): | |
bits = [f"{self.AssociatedQuality}:"] | |
if self.Level: | |
sign = ('' if (self.Level < 0) else '+') | |
bits.append(f" {sign}{self.Level}") | |
if self.SetToExactly: | |
bits.append(f" = {self.SetToExactly}") | |
if self.SetToExactlyAdvanced: | |
bits.append(f" = {self.SetToExactlyAdvanced}") | |
if self.OnlyIfAtLeast: | |
bits.append(f" (only if at least {self.OnlyIfAtLeast})") | |
if self.OnlyIfAtLeastAdvanced: | |
bits.append(f" (only if no more than {self.OnlyIfAtLeastAdvanced})") | |
if self.OnlyIfNoMoreThan: | |
bits.append(f" (only if no more than {self.OnlyIfNoMoreThan})") | |
if self.OnlyIfNoMoreThanAdvanced: | |
bits.append(f" (only if no more than {self.OnlyIfNoMoreThanAdvanced})") | |
if self.TargetQuality: | |
bits.append(f" (target: {self.TargetQuality} at level {self.TargetLevel})") | |
return "".join(bits) | |
def __repr__(self): | |
return str(self) | |
class BinarySerializer_EventQEffect: | |
@classmethod | |
def Deserialize(cls, bs): | |
eventQEffect = EventQEffect() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
eventQEffect.Priority = bs.ReadInt32() | |
eventQEffect.ForceEquip = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
eventQEffect.OnlyIfNoMoreThanAdvanced = bs.ReadString() | |
if bs.ReadBoolean(): | |
eventQEffect.OnlyIfAtLeast = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
eventQEffect.OnlyIfNoMoreThan = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
eventQEffect.SetToExactlyAdvanced = bs.ReadString() | |
if bs.ReadBoolean(): | |
eventQEffect.ChangeByAdvanced = bs.ReadString() | |
if bs.ReadBoolean(): | |
eventQEffect.OnlyIfAtLeastAdvanced = bs.ReadString() | |
if bs.ReadBoolean(): | |
eventQEffect.SetToExactly = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
eventQEffect.TargetQuality = BinarySerializer_Quality.Deserialize(bs) | |
if bs.ReadBoolean(): | |
eventQEffect.TargetLevel = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
eventQEffect.CompletionMessage = bs.ReadString() | |
eventQEffect.Level = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
eventQEffect.AssociatedQuality = BinarySerializer_Quality.Deserialize(bs) | |
eventQEffect.Id = bs.ReadInt32() | |
return eventQEffect | |
class EventQRequirement: | |
def __str__(self): | |
Quality = getattr(self, 'AssociatedQuality', None) | |
QualityId = getattr(Quality, 'Id', 0) | |
MinLevel = getattr(self, 'MinLevel', -1) | |
MaxLevel = getattr(self, 'MaxLevel', -1) | |
MinAdvanced = getattr(self, 'MinAdvanced', -1) | |
MaxAdvanced = getattr(self, 'MaxAdvanced', -1) | |
return f"Requires Quality {QualityId}, Min: {MinLevel}, Max: {MaxLevel}, MinAdvanced: {MinAdvanced}, MaxAdvanced: {MaxAdvanced}" | |
def __repr__(self): | |
return str(self) | |
class BinarySerializer_EventQRequirement: | |
@classmethod | |
def Deserialize(cls, bs): | |
eventQRequirement = EventQRequirement() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
eventQRequirement.MinLevel = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
eventQRequirement.MaxLevel = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
eventQRequirement.MinAdvanced = bs.ReadString() | |
if bs.ReadBoolean(): | |
eventQRequirement.MaxAdvanced = bs.ReadString() | |
if bs.ReadBoolean(): | |
eventQRequirement.AssociatedQuality = BinarySerializer_Quality.Deserialize(bs) | |
eventQRequirement.Id = bs.ReadInt32() | |
return eventQRequirement | |
class BinarySerializer_Frequency: | |
@classmethod | |
def Deserialize(cls, bs): | |
frequency = 0 # Frequency.Sometimes | |
return bs.ReadInt32() | |
class BinarySerializer_Genre: | |
@classmethod | |
def Deserialize(cls, bs): | |
genre = 0 # Genre.NotYetSpecified= | |
return bs.ReadInt32() | |
class BinarySerializer_LoggedInVia: | |
@classmethod | |
def Deserialize(cls, bs): | |
loggedInVia = 0 # LoggedInVia.Web | |
return bs.ReadInt32() | |
class BinarySerializer_Nature: | |
@classmethod | |
def Deserialize(cls, bs): | |
nature = 0 # Nature.Unspecified | |
return bs.ReadInt32() | |
class BinarySerializer_PrivilegeLevel: | |
@classmethod | |
def Deserialize(cls, bs): | |
privilegeLevel = 0 # PrivilegeLevel.User | |
return bs.ReadInt32() | |
class BinarySerializer_PublishState: | |
@classmethod | |
def Deserialize(cls, bs): | |
publishState = 0 # PublishState.UnPublished | |
return bs.ReadInt32() | |
class QEnhancement: | |
def __init__(self): | |
self.Level = 0 | |
self.AssociatedQuality = None | |
self.Id = 0 | |
def __str__(self): | |
sign = ('' if (self.Level < 0) else '+') | |
return f"Enhancement: {self.AssociatedQuality} {sign}{self.Level}" | |
def __repr__(self): | |
return __str__(self) | |
class BinarySerializer_QEnhancement: | |
@classmethod | |
def Deserialize(cls, bs): | |
qEnhancement = QEnhancement() | |
if not bs.ReadBoolean(): | |
return None | |
qEnhancement.Level = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
qEnhancement.AssociatedQuality = BinarySerializer_Quality.Deserialize(bs) | |
qEnhancement.Id = bs.ReadInt32() | |
return qEnhancement | |
# public enum QualityAllowedOn | |
# { | |
# Unspecified, | |
# Character, | |
# QualityAndCharacter, | |
# Event, | |
# Branch, | |
# Persona, | |
# User | |
# } | |
# public enum DifficultyTestType | |
# { | |
# Broad, | |
# Narrow | |
# } | |
# public enum Nature | |
# { | |
# Unspecified, | |
# Status, | |
# Thing | |
# } | |
# public enum Category | |
# { | |
# Academic = 16000, | |
# Accomplishment = 5050, | |
# Acquaintance = 5025, | |
# Advantage = 160, | |
# Affiliation = 13000, | |
# Ambition = 7000, | |
# Avatar = 39000, | |
# BasicAbility = 1000, | |
# Boots = 105, | |
# Cartography = 17000, | |
# Circumstance = 37000, | |
# Clothing = 107, | |
# Club = 12000, | |
# Companion = 106, | |
# ConstantCompanion = 11000, | |
# Contacts = 6000, | |
# Contraband = 18000, | |
# Curiosity = 150, | |
# Currency = 1, | |
# Destiny = 60000, | |
# Document = 170, | |
# Dreams = 5002, | |
# Elder = 19000, | |
# Gloves = 104, | |
# Goods = 200, | |
# GreatGame = 70001, | |
# Hat = 103, | |
# HomeComfort = 15000, | |
# Infernal = 20000, | |
# Influence = 21000, | |
# Intrigue = 5001, | |
# Key = 45000, | |
# Knowledge = 50000, | |
# Legal = 29000, | |
# Literature = 22000, | |
# Lodgings = 22500, | |
# Luminosity = 23000, | |
# MajorLateral = 34000, | |
# Menace = 5500, | |
# MinorLateral = 36000, | |
# Modfier = 70000, | |
# Mysteries = 24000, | |
# Nostalgia = 25000, | |
# Objective = 40000, | |
# Profession = 3000, | |
# Progress = 5200, | |
# Quest = 35000, | |
# Quirk = 5004, | |
# RagTrade = 26000, | |
# Ratness = 27000, | |
# Reputation = 5003, | |
# Route = 8000, | |
# Rubbery = 32000, | |
# Rumour = 28000, | |
# Sustenance = 70003, | |
# Seasonal = 9000, | |
# Ship = 10000, | |
# SidebarAbility = 33000, | |
# SpecificAbility = 2000, | |
# Story = 5000, | |
# Timer = 13999, | |
# Transportation = 14000, | |
# Unspecified = 0, | |
# Venture = 5100, | |
# Weapon = 101, | |
# WildWords = 30000, | |
# Wines = 31000, | |
# Hidden = 6661, | |
# Randomizer = 6662, | |
# ZeeTreasures = 70002, | |
# Bridge = 70004, | |
# Plating = 70005, | |
# Auxiliary = 70006, | |
# SmallWeapon = 70007, | |
# LargeWeapon = 70008, | |
# Scout = 70009 | |
# } | |
class Quality: | |
def __init__(self): | |
self.Id = 0 # From Entity | |
self.Name = '' # from EntityWithName | |
self.QualitiesPossessedList = [] | |
self.RelationshipCapable = False | |
self.PluralName = '' | |
self.OwnerName = '' | |
self.Description = '' | |
self.Image = '' | |
self.Notes = '' | |
self.Tag = '' | |
self.Cap = 0 # int? | |
self.CapAdvanced = '' | |
self.HimbleLevel = 0 | |
self.UsePyramidNumbers = False | |
self.PyramidNumberIncreaseLimit = 0 | |
self.AvailableAt = '' | |
self.PreventNaming = False | |
self.CssClasses = '' | |
self.QEffectPriority = 0 | |
self.QEffectMinimalLimit = 0 # int? | |
self.World = None # World | |
self.Ordering = 0 | |
self.IsSlot = False | |
self.LimitedToArea = None # Area | |
self.AssignToSlot = None # Quality | |
self.ParentQuality = None # Quality | |
self.Persistent = False | |
self.Visible = False | |
self.Enhancements = [] | |
self.EnhancementsDescription = '' | |
self.SecondChanceQuality = None # Quality | |
self.UseEvent = None # Event | |
self.DifficultyTestType = 0 # DifficultyTestType | |
self.DifficultyScaler = 0 | |
self.AllowedOn = 0 # QualityAllowedOn | |
self.Nature = 0 # Nature | |
self.Category = 0 # Category | |
self.LevelDescriptionText = '' | |
self.ChangeDescriptionText = '' | |
self.DescendingChangeDescriptionText = '' | |
self.LevelImageText = '' | |
self.VariableDescriptionText = '' | |
def __str__(self): | |
return f"[{self.Id}: {self.Name}]" | |
def __repr__(self): | |
return str(self) | |
class BinarySerializer_Quality: | |
@classmethod | |
def Deserialize(cls, bs, debug=False): | |
if debug: bs.debug_dump('Quality begins') | |
quality = Quality() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
quality.QualitiesPossessedList = [] | |
num = bs.ReadInt32() | |
for i in range(num): | |
quality.QualitiesPossessedList.append(BinarySerializer_AspectQPossession.Deserialize(bs)) | |
quality.RelationshipCapable = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
quality.PluralName = bs.ReadString() | |
if debug: print(f"PluralName: {quality.PluralName}") | |
if bs.ReadBoolean(): | |
quality.OwnerName = bs.ReadString() | |
if debug: print(f"OwnerName: {quality.OwnerName}") | |
if bs.ReadBoolean(): | |
quality.Description = bs.ReadString() | |
if debug: print(f"Description: {quality.Description}") | |
if bs.ReadBoolean(): | |
quality.Image = bs.ReadString() | |
if debug: print(f"Image: {quality.Image}") | |
if bs.ReadBoolean(): | |
quality.Notes = bs.ReadString() | |
if debug: print(f"Notes: {quality.Notes}") | |
if bs.ReadBoolean(): | |
quality.Tag = bs.ReadString() | |
if debug: print(f"Tag: {quality.Tag}") | |
if bs.ReadBoolean(): | |
quality.Cap = bs.ReadInt32() | |
if debug: print(f"Cap: {quality.Cap}") | |
if bs.ReadBoolean(): | |
quality.CapAdvanced = bs.ReadString() | |
if debug: print(f"CapAdvanced: {quality.CapAdvanced}") | |
quality.HimbleLevel = bs.ReadInt32() | |
if debug: print(f"HimbleLevel: {quality.HimbleLevel}") | |
if debug: bs.debug_dump('checkpoint') | |
quality.UsePyramidNumbers = bs.ReadBoolean() | |
if debug: print(f"UsePyramidNumbers: {quality.UsePyramidNumbers}") | |
quality.PyramidNumberIncreaseLimit = bs.ReadInt32() | |
if debug: print(f"PyramidNumberIncreaseLimit: {quality.PyramidNumberIncreaseLimit}") | |
if bs.ReadBoolean(): | |
quality.AvailableAt = bs.ReadString() | |
if debug: print(f"AvailableAt: {quality.AvailableAt}") | |
quality.PreventNaming = bs.ReadBoolean() | |
if debug: print(f"PreventNaming: {quality.PreventNaming}") | |
if bs.ReadBoolean(): | |
quality.CssClasses = bs.ReadString() | |
if debug: print(f"CssClasses: {quality.CssClasses}") | |
quality.QEffectPriority = bs.ReadInt32() | |
if debug: print(f"QEffectPriority: {quality.QEffectPriority}") | |
if bs.ReadBoolean(): | |
quality.QEffectMinimalLimit = bs.ReadInt32() | |
if debug: print(f"QEffectMinimalLimit: {quality.QEffectMinimalLimit}") | |
if bs.ReadBoolean(): | |
quality.World = BinarySerializer_World.Deserialize(bs) | |
if debug: print(f"World: {quality.World}") | |
quality.Ordering = bs.ReadInt32() | |
if debug: print(f"Ordering: {quality.Ordering}") | |
quality.IsSlot = bs.ReadBoolean() | |
if debug: print(f"IsSlot: {quality.IsSlot}") | |
if bs.ReadBoolean(): | |
quality.LimitedToArea = BinarySerializer_Area.Deserialize(bs) | |
if debug: print(f"LimitedToArea: {quality.LimitedToArea}") | |
if bs.ReadBoolean(): | |
if debug: bs.debug_dump('AssignToSlot quality!') | |
quality.AssignToSlot = cls.Deserialize(bs) | |
if debug: print(f"AssignToSlot: {quality.AssignToSlot}") | |
if bs.ReadBoolean(): | |
if debug: bs.debug_dump('ParentQuality thing!') | |
quality.ParentQuality = cls.Deserialize(bs) | |
if debug: print(f"ParentQuality: {quality.ParentQuality}") | |
quality.Persistent = bs.ReadBoolean() | |
if debug: print(f"Persistent: {quality.Persistent}") | |
quality.Visible = bs.ReadBoolean() | |
if debug: print(f"Visible: {quality.Visible}") | |
if bs.ReadBoolean(): | |
quality.Enhancements = [] | |
num2 = bs.ReadInt32() | |
if debug: print(f"Enhancements (count): {num2}") | |
for j in range(num2): | |
quality.Enhancements.append(BinarySerializer_QEnhancement.Deserialize(bs)) | |
if bs.ReadBoolean(): | |
quality.EnhancementsDescription = bs.ReadString() | |
if debug: print(f"EnhancementsDescription: {quality.EnhancementsDescription}") | |
if bs.ReadBoolean(): | |
quality.SecondChanceQuality = BinarySerializer_Quality.Deserialize(bs) | |
if debug: print(f"SecondChanceQuality: {quality.SecondChanceQuality}") | |
if bs.ReadBoolean(): | |
if debug: bs.debug_dump('UseEvent thing!') | |
quality.UseEvent = BinarySerializer_Event.Deserialize(bs, debug=debug) | |
if debug: print(f"UseEvent: {quality.UseEvent}") | |
quality.DifficultyTestType = BinarySerializer_DifficultyTestType.Deserialize(bs) | |
if debug: print(f"DifficultyTestType: {quality.DifficultyTestType}") | |
quality.DifficultyScaler = bs.ReadInt32() | |
if debug: print(f"DifficultyScaler: {quality.DifficultyScaler}") | |
quality.AllowedOn = BinarySerializer_QualityAllowedOn.Deserialize(bs) | |
if debug: print(f"AllowedOn: {quality.AllowedOn}") | |
quality.Nature = BinarySerializer_Nature.Deserialize(bs) | |
if debug: print(f"Nature: {quality.Nature}") | |
quality.Category = BinarySerializer_Category.Deserialize(bs) | |
if debug: print(f"Category: {quality.Category}") | |
if debug: bs.debug_dump('just about to break') | |
if bs.ReadBoolean(): | |
quality.LevelDescriptionText = bs.ReadString() | |
if debug: print(f"LevelDescriptionText: {quality.LevelDescriptionText}") | |
if bs.ReadBoolean(): | |
quality.ChangeDescriptionText = bs.ReadString() | |
if debug: print(f"ChangeDescriptionText: {quality.ChangeDescriptionText}") | |
if bs.ReadBoolean(): | |
quality.DescendingChangeDescriptionText = bs.ReadString() | |
if debug: print(f"DescendingChangeDescriptionText: {quality.DescendingChangeDescriptionText}") | |
if bs.ReadBoolean(): | |
quality.LevelImageText = bs.ReadString() | |
if debug: print(f"LevelImageText: {quality.LevelImageText}") | |
if bs.ReadBoolean(): | |
quality.VariableDescriptionText = bs.ReadString() | |
if debug: print(f"VariableDescriptionText: {quality.VariableDescriptionText}") | |
if bs.ReadBoolean(): | |
quality.Name = bs.ReadString() | |
if debug: print(f"Name: {quality.Name}") | |
quality.Id = bs.ReadInt32() | |
if debug: print(f"Id: {quality.Id}") | |
return quality | |
@classmethod | |
def DeserializeCollection(cls, bs): | |
l = [] | |
num = bs.ReadInt32() | |
for i in range(num): | |
_start = bs.offset | |
l.append(cls.Deserialize(bs, debug=False)) | |
q = l[-1] | |
return l | |
class BinarySerializer_QualityAllowedOn: | |
@classmethod | |
def Deserialize(cls, bs): | |
qualityAllowedOn = 0 # QualityAllowedOn.Unspecified | |
return bs.ReadInt32() | |
class Setting: | |
pass | |
class BinarySerializer_Setting: | |
@classmethod | |
def Deserialize(cls, bs): | |
setting = Setting() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
setting.World = BinarySerializer_World.Deserialize(bs) | |
if bs.ReadBoolean(): | |
setting.OwnerName = bs.ReadString() | |
if bs.ReadBoolean(): | |
setting.Personae = [] | |
num = bs.ReadInt32() | |
for i in range(num): | |
setting.Personae.append(BinarySerializer_Persona.Deserialize(bs)) | |
if bs.ReadBoolean(): | |
setting.StartingArea = BinarySerializer_Area.Deserialize(bs) | |
if bs.ReadBoolean(): | |
setting.StartingDomicile = BinarySerializer_Domicile.Deserialize(bs) | |
setting.ItemsUsableHere = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
setting.Exchange = BinarySerializer_Exchange.Deserialize(bs) | |
setting.TurnLengthSeconds = bs.ReadInt32() | |
setting.MaxActionsAllowed = bs.ReadInt32() | |
setting.MaxCardsAllowed = bs.ReadInt32() | |
setting.ActionsInPeriodBeforeExhaustion = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
setting.Description = bs.ReadString() | |
if bs.ReadBoolean(): | |
setting.Name = bs.ReadString() | |
setting.Id = bs.ReadInt32() | |
return setting | |
@classmethod | |
def DeserializeCollection(cls, bs): | |
l = [] | |
num = bs.ReadInt32() | |
for i in range(num): | |
l.append(cls.Deserialize(bs)) | |
return l | |
class BinarySerializer_Urgency: | |
@classmethod | |
def Deserialize(cls, bs): | |
urgency = 0 #Urgency.Normal | |
return bs.ReadInt32() | |
class User: | |
pass | |
class BinarySerializer_User: | |
@classmethod | |
def Deserialize(cls, bs): | |
user = User() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
user.QualitiesPossessedList = [] | |
num = bs.ReadInt32() | |
for i in range(num): | |
user.QualitiesPossessedList.append(BinarySerializer_UserQPossession.Deserialize(bs)) | |
if bs.ReadBoolean(): | |
user.Name = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.StartedInWorld = BinarySerializer_World.Deserialize(bs) | |
if bs.ReadBoolean(): | |
user.EmailAddress = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.FacebookEmail = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.PasswordHash = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.ConfirmationCode = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.TwitterId = bs.ReadInt64() | |
if bs.ReadBoolean(): | |
user.FacebookId = bs.ReadInt64() | |
if bs.ReadBoolean(): | |
user.GoogleId = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.GoogleAuthToken = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.GoogleAuthTokenSecret = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.GoogleEmail = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.TwitterAuthToken = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.TwitterAuthTokenSecret = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.FacebookAuthToken = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.FacebookAuthTokenSecret = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.Source = bs.ReadString() | |
user.EnteredViaContentId = bs.ReadInt32() | |
user.EnteredViaCharacterId = bs.ReadInt32() | |
user.Status = BinarySerializer_UserStatus.Deserialize(bs) | |
user.EmailVerified = bs.ReadBoolean() | |
user.EchoViaNetwork = BinarySerializer_ViaNetwork.Deserialize(bs) | |
user.MessageViaNetwork = BinarySerializer_ViaNetwork.Deserialize(bs) | |
user.MessageAboutNastiness = bs.ReadBoolean() | |
user.MessageAboutNiceness = bs.ReadBoolean() | |
user.MessageAboutAnnouncements = bs.ReadBoolean() | |
user.StoryEventMessage = bs.ReadBoolean() | |
user.DefaultPrivilegeLevel = BinarySerializer_PrivilegeLevel.Deserialize(bs) | |
user.LoggedInVia = BinarySerializer_LoggedInVia.Deserialize(bs) | |
user.IsBroadcastTarget = bs.ReadBoolean() | |
user.MysteryPrizeTracking = bs.ReadInt32() | |
user.Recruited = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
user.TempId = bs.ReadString() | |
user.CreatedAt = BinarySerializer_DateTime.Deserialize(bs) | |
if bs.ReadBoolean(): | |
user.LastLoggedInAt = BinarySerializer_DateTime.Deserialize(bs) | |
if bs.ReadBoolean(): | |
user.LastActiveAt = BinarySerializer_DateTime.Deserialize(bs) | |
if bs.ReadBoolean(): | |
user.IP = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.LastAccessCode = bs.ReadString() | |
if bs.ReadBoolean(): | |
user.WorldPrivileges = [] | |
num2 = bs.ReadInt32() | |
for j in range(num2): | |
user.WorldPrivileges.append(BinarySerializer_UserWorldPrivilege.Deserialize(bs)) | |
user.SRPurchasedNexInLifetime = bs.ReadInt32() | |
user.FatePointsGainedThroughGameInLifetime = bs.ReadInt32() | |
user.Nex = bs.ReadInt32() | |
user.Id = bs.ReadInt32() | |
####### | |
print() | |
print(f"*** USER {user.Id}:") | |
for k in sorted(user.__dict__.keys()): | |
print(" %s: %s" % (k, user.__dict__[k])) | |
print() | |
####### | |
return user | |
class UserQPossession: | |
pass | |
class BinarySerializer_UserQPossession: | |
@classmethod | |
def Deserialize(cls, bs): | |
userQPossession = UserQPossession() | |
if not bs.ReadBoolean(): | |
return None | |
userQPossession.XP = bs.ReadInt32() | |
userQPossession.EffectiveLevelModifier = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
userQPossession.TargetQuality = BinarySerializer_Quality.Deserialize(bs) | |
if bs.ReadBoolean(): | |
userQPossession.TargetLevel = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
userQPossession.CompletionMessage = bs.ReadString() | |
userQPossession.Level = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
userQPossession.AssociatedQuality = BinarySerializer_Quality.Deserialize(bs) | |
userQPossession.Id = bs.ReadInt32() | |
return userQPossession | |
class BinarySerializer_UserStatus: | |
@classmethod | |
def Deserialize(cls, bs): | |
userStatus = 0 # UserStatus.AwaitingEmailConfirmation | |
return bs.ReadInt32() | |
class UserWorldPrivilege: | |
pass | |
class BinarySerializer_UserWorldPrivilege: | |
@classmethod | |
def Deserialize(cls, bs): | |
userWorldPrivilege = UserWorldPrivilege() | |
if not bs.ReadBoolean(): | |
return None | |
if bs.ReadBoolean(): | |
userWorldPrivilege.World = BinarySerializer_World.Deserialize(bs) | |
userWorldPrivilege.PrivilegeLevel = BinarySerializer_PrivilegeLevel.Deserialize(bs) | |
if bs.ReadBoolean(): | |
userWorldPrivilege.User = BinarySerializer_User.Deserialize(bs) | |
userWorldPrivilege.Id = bs.ReadInt32() | |
return userWorldPrivilege | |
class BinarySerializer_ViaNetwork: | |
@classmethod | |
def Deserialize(cls, bs): | |
viaNetwork = 0 # ViaNetwork.None | |
return bs.ReadInt32() | |
class World: | |
pass | |
class BinarySerializer_World: | |
@classmethod | |
def Deserialize(cls, bs): | |
world = World() | |
if not bs.ReadBoolean(): | |
return None | |
world.GeneralQualityCatalogue = bs.ReadBoolean() | |
world.ShowCardTitles = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
world.CharacterCreationPageText = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.EndPageText = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.FrontPageText = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.CustomCss = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.Credits = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.Description = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.Name = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.Domain = bs.ReadString() | |
world.Promoted = bs.ReadInt32() | |
if bs.ReadBoolean(): | |
world.DefaultSetting = BinarySerializer_Setting.Deserialize(bs) | |
world.FacebookAuth = bs.ReadBoolean() | |
world.TwitterAuth = bs.ReadBoolean() | |
world.EmailAuth = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
world.FacebookAPIKey = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.FacebookAppId = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.FacebookAppSecret = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.GameUserTwitterAuthToken = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.GameUserTwitterAuthTokenSecret = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.TwitterConsumerKey = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.TwitterConsumerSecret = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.TwitterCallbackUrl = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.AmazonHostedImageUrl = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.AmazonBucketName = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.StyleSheet = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.LogoImage = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.DefaultStartingSetting = BinarySerializer_Setting.Deserialize(bs) | |
if bs.ReadBoolean(): | |
world.Owner = BinarySerializer_User.Deserialize(bs) | |
world.IsPortalWorld = bs.ReadBoolean() | |
world.Monetizes = bs.ReadBoolean() | |
if bs.ReadBoolean(): | |
world.PaymentEmailAddress = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.SupportEmailAddress = bs.ReadString() | |
if bs.ReadBoolean(): | |
world.SystemFromEmailAddress = bs.ReadString() | |
world.LastUpdated = BinarySerializer_DateTime.Deserialize(bs) | |
if bs.ReadBoolean(): | |
world.UpdateNotes = bs.ReadString() | |
world.PublishState = BinarySerializer_PublishState.Deserialize(bs) | |
world.Genre = BinarySerializer_Genre.Deserialize(bs) | |
world.Id = bs.ReadInt32() | |
####### | |
print() | |
print(f"*** WORLD {world.Id}:") | |
for k in sorted(world.__dict__.keys()): | |
print(" %s: %s" % (k, world.__dict__[k])) | |
print() | |
####### | |
return world | |
def main(): | |
# Qualities | |
data = open('qualities.dat', 'rb').read() | |
bs = BinaryReader(data) | |
bs.Seek(0x14) # Skip Unity resource bits | |
qualities = BinarySerializer_Quality.DeserializeCollection(bs) | |
# Events | |
data = open('events.dat', 'rb').read() | |
bs = BinaryReader(data) | |
bs.Seek(0x10) # Skip Unity resource bits | |
events = BinarySerializer_Event.DeserializeCollection(bs) | |
def get_quality(id): | |
for q in qualities: | |
if q.Id == id: | |
return q | |
return None | |
def get_event(id): | |
for e in events: | |
if e.Id == id: | |
return e | |
return None | |
def save(): | |
with open('qualities.txt', 'w') as output: | |
for q in qualities: | |
output.write(str(q)) | |
output.write('\n') | |
with open('events.txt', 'w') as output: | |
for e in events: | |
output.write(str(e)) | |
output.write('\n') | |
print("Qualities and events saved.") | |
print("call save() to save qualities and events as text files.") | |
print("or explore 'events' and 'qualities' lists interactively.") | |
print() | |
# Shell | |
import code | |
variables = globals().copy() | |
variables.update(locals()) | |
shell = code.InteractiveConsole(variables) | |
shell.interact() | |
if __name__ == '__main__': main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment