Skip to content

Commit

Permalink
Added load and save of persistent items and timers, updated Stream
Browse files Browse the repository at this point in the history
  • Loading branch information
0x5abe committed Jul 18, 2024
1 parent b9c2178 commit e0de697
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 68 deletions.
6 changes: 4 additions & 2 deletions docs/PSF.hexpat
Original file line number Diff line number Diff line change
Expand Up @@ -658,12 +658,12 @@ struct EffectManagerState {
vector<CollisionTriggerAction> m_vectorCollisionTriggerAction;
vector<ToggleTriggerAction> m_vectorToggleTriggerAction;
vector<SpawnTriggerAction> m_vectorSpawnTriggerAction;
unordered_map<s32,s32> m_unorderedMapInt_int;
unordered_map<s32,s32> m_itemCountMap;
unordered_map<s32,bool> m_unorderedMapInt_bool;
vector<GroupCommandObject2> m_vectorGroupCommandObject2;
unordered_map<s32,pair<double,double>> m_unorderedMapInt_pair_double_double;
unordered_set<s32> m_unorderedSet_int2;
unordered_map<s32,TimerItem> m_unorderedMapInt_TimerItem;
unordered_map<s32,TimerItem> m_timerItemMap;
unordered_map<s32,vector<TimerTriggerAction>> m_unorderedMapInt_vectorTimerTriggerAction;
};

Expand Down Expand Up @@ -721,6 +721,8 @@ struct PSF {
CheckpointObject checkpointObjects[checkpointObjectCount];
u32 activatedCheckpointCount;
CheckpointGameObjectPtr activatedCheckpoints[activatedCheckpointCount];
unordered_map<s32,s32> m_persistentItemCountMap;
unordered_set<s32> m_persistentTimerItemSet;
};

PSF file @ 0x0;
2 changes: 1 addition & 1 deletion mod.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"geode": "3.1.1",
"geode": "3.2.0",
"gd": {
"win": "2.206"
},
Expand Down
4 changes: 2 additions & 2 deletions src/domain/CheckpointGameObjectReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
using namespace geode::prelude;
using namespace persistenceAPI;

void CheckpointGameObjectReference::load(InputStream& i_stream) {
void CheckpointGameObjectReference::load(Stream& i_stream) {
int l_objectIndex;
i_stream >> l_objectIndex;
persistenceAPI::PAPlayLayer* l_playLayer = static_cast<persistenceAPI::PAPlayLayer*>(PlayLayer::get());
if (l_playLayer) m_reference = static_cast<CheckpointGameObject*>(l_playLayer->getGameObject(l_objectIndex));
}

void CheckpointGameObjectReference::save(OutputStream& o_stream) {
void CheckpointGameObjectReference::save(Stream& o_stream) {
int l_objectIndex = -1;
persistenceAPI::PAPlayLayer* l_playLayer = static_cast<persistenceAPI::PAPlayLayer*>(PlayLayer::get());
if (l_playLayer) l_objectIndex = l_playLayer->getGameObjectIndex(m_reference);
Expand Down
4 changes: 2 additions & 2 deletions src/domain/CheckpointGameObjectReference.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ class CheckpointGameObjectReference {
m_reference = i_reference;
}

void load(persistenceAPI::InputStream& i_stream);
void save(persistenceAPI::OutputStream& o_stream);
void load(persistenceAPI::Stream& i_stream);
void save(persistenceAPI::Stream& o_stream);
};
8 changes: 4 additions & 4 deletions src/hooks/CheckpointObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@
using namespace geode::prelude;
using namespace persistenceAPI;

void PSCheckpointObject::load(InputStream& i_stream) {
void PSCheckpointObject::load(Stream& i_stream) {
reinterpret_cast<PACCNode*>(this)->load(i_stream);
i_stream >> *this;
}

void PSCheckpointObject::save(OutputStream& o_stream) {
void PSCheckpointObject::save(Stream& o_stream) {
//log::info("SAVING CHECKPOINT OBJECT");
reinterpret_cast<PACCNode*>(this)->save(o_stream);
o_stream << *this;
}

inline void operator>>(InputStream& i_stream, PSCheckpointObject& o_value) {
inline void operator>>(Stream& i_stream, PSCheckpointObject& o_value) {
// GJGameState m_gameState;
//log::info("INPUT CCNODE uid: {}", o_value.m_uID);
//log::info("INPUT CCNODE frotationx: {}", o_value.m_fRotationX);
Expand Down Expand Up @@ -134,7 +134,7 @@ inline void operator>>(InputStream& i_stream, PSCheckpointObject& o_value) {
o_value.m_fields->m_wasLoaded = true;
}

inline void operator<<(OutputStream& o_stream, PSCheckpointObject& i_value) {
inline void operator<<(Stream& o_stream, PSCheckpointObject& i_value) {
//log::info("OUTPUT CCNODE uid: {}", i_value.m_uID);
//log::info("OUTPUT CCNODE frotationx: {}", i_value.m_fRotationX);
//log::info("OUTPUT CCNODE scale y: {}", i_value.m_fScaleY);
Expand Down
8 changes: 4 additions & 4 deletions src/hooks/CheckpointObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

class $modify(PSCheckpointObject, CheckpointObject) {
protected:
friend void operator>>(persistenceAPI::InputStream& i_stream, PSCheckpointObject& o_value);
friend void operator<<(persistenceAPI::OutputStream& o_stream, PSCheckpointObject& i_value);
friend void operator>>(persistenceAPI::Stream& i_stream, PSCheckpointObject& o_value);
friend void operator<<(persistenceAPI::Stream& o_stream, PSCheckpointObject& i_value);

public:
struct Fields {
Expand All @@ -16,8 +16,8 @@ class $modify(PSCheckpointObject, CheckpointObject) {
long long m_timestamp;
};

void load(persistenceAPI::InputStream& i_stream);
void save(persistenceAPI::OutputStream& o_stream);
void load(persistenceAPI::Stream& i_stream);
void save(persistenceAPI::Stream& o_stream);

void clean();

Expand Down
33 changes: 30 additions & 3 deletions src/hooks/PlayLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ using namespace geode::prelude;
using namespace persistenceAPI;

PSPlayLayer* s_currentPlayLayer = nullptr;
char s_psfMagicAndVer[] = "PSF v0.0.7";
char s_psfMagicAndVer[] = "PSF v0.0.8";
int s_psfVersion = 8;

// overrides

Expand Down Expand Up @@ -114,6 +115,11 @@ void PSPlayLayer::postUpdate(float i_unkFloat) {
m_fields->m_triedPlacingCheckpoint = m_tryPlaceCheckpoint;

PlayLayer::postUpdate(i_unkFloat);

if (m_fields->m_updatePersistentTimerItemSet) {
m_fields->m_updatePersistentTimerItemSet = false;
m_effectManager->m_persistentTimerItemSet = m_fields->m_loadedPersistentTimerItemSet;
}

m_fields->m_inPostUpdate = false;
m_fields->m_triedPlacingCheckpoint = false;
Expand Down Expand Up @@ -264,6 +270,10 @@ void PSPlayLayer::showSavingProgressCircleSprite(bool i_show) {
m_fields->m_savingProgressCircleSprite->setVisible(false);
}

void PSPlayLayer::endStream() {
m_fields->m_stream.end();
}

bool PSPlayLayer::canSave() {
if (!savesEnabled()) {
return false;
Expand All @@ -284,7 +294,24 @@ void PSPlayLayer::removeSaveFile(int i_slot) {
if (i_slot == -1) {
i_slot = m_fields->m_saveSlot;
}
endInputStream();
endOutputStream();
endStream();
util::filesystem::removeSaveFile(m_level, i_slot);
}

bool PSPlayLayer::updatePsfFormat() {
switch (m_fields->m_readPsfVersion) {
case 7: {
m_fields->m_stream.seek(0);
m_fields->m_stream.write(s_psfMagicAndVer,sizeof(s_psfMagicAndVer));
m_fields->m_stream.seek(0, true);
m_fields->m_stream.clear();
m_fields->m_stream.writeZero(2*sizeof(int));
m_fields->m_stream.seek(sizeof(s_psfMagicAndVer));
m_fields->m_readPsfVersion = s_psfVersion;
return true;
}
default: {
return false;
}
}
}
19 changes: 11 additions & 8 deletions src/hooks/PlayLayer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class PSPlayLayer;

extern PSPlayLayer* s_currentPlayLayer;
extern char s_psfMagicAndVer[11];
extern int s_psfVersion;

enum class LoadingState {
Ready,
Expand All @@ -27,7 +28,7 @@ enum class LoadingState {
ReadCheckpointCount,
ReadCheckpoint,
ReadActivatedCheckpoints,
ReadTimePlayed,
ReadExtraData,
WaitingForPopup,
CancelLevelLoad
};
Expand All @@ -37,7 +38,7 @@ enum class SavingState {
Setup,
SaveCheckpoint,
SaveActivatedCheckpoints,
SaveTimePlayed
SaveExtraData
};

class $modify(PSPlayLayer, PlayLayer) {
Expand All @@ -53,22 +54,24 @@ class $modify(PSPlayLayer, PlayLayer) {
bool m_exitAfterSave = false;
bool m_editorNoticeClosed = false;
bool m_cancelLevelLoad = false;
bool m_updatePersistentTimerItemSet = false;
int m_saveSlot = -1;
int m_uniqueIdBase = 12;
int m_readPsfVersion = -1;
unsigned int m_remainingCheckpointLoadCount = 0;
unsigned int m_remainingCheckpointSaveCount = 0;
unsigned int m_bytesToRead = 0;
unsigned int m_bytesRead = 0;
float m_loadingProgress = 0.0f;
long long m_lastSavedCheckpointTimestamp = 0;
persistenceAPI::InputStream m_inputStream;
persistenceAPI::OutputStream m_outputStream;
persistenceAPI::Stream m_stream;
LoadingState m_loadingState = LoadingState::Setup;
SavingState m_savingState = SavingState::Ready;
cocos2d::CCScene* m_transitionFadeScene = nullptr;
geode::Ref<cocos2d::CCSprite> m_savingProgressCircleSprite = nullptr;
geode::Ref<cocos2d::CCArray> m_normalModeCheckpoints = nullptr;
std::vector<CheckpointGameObjectReference> m_activatedCheckpoints;
gd::unordered_set<int> m_loadedPersistentTimerItemSet;
};

// overrides
Expand Down Expand Up @@ -115,7 +118,7 @@ class $modify(PSPlayLayer, PlayLayer) {

bool readPsfLevelStringHash();

bool readPsfVersion();
bool readPsfVersionAndUpdateIfNecessary();

bool readPsfFinishedSaving();

Expand Down Expand Up @@ -153,13 +156,13 @@ class $modify(PSPlayLayer, PlayLayer) {

void showSavingProgressCircleSprite(bool i_show);

void endOutputStream();

void endInputStream();
void endStream();

bool canSave();

bool savesEnabled();

void removeSaveFile(int i_slot = -1);

bool updatePsfFormat();
};
45 changes: 24 additions & 21 deletions src/hooks/PlayLayerLoad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ using namespace persistenceAPI;
bool PSPlayLayer::readPsfLevelStringHash() {
unsigned int l_savedLevelStringHash;

m_fields->m_inputStream >> l_savedLevelStringHash;
m_fields->m_stream >> l_savedLevelStringHash;

if (l_savedLevelStringHash != util::algorithm::hash_string(m_level->m_levelString.c_str())) {
//log::info("[readPsfLevelStringHash] different levelstring hash");
Expand All @@ -20,13 +20,17 @@ bool PSPlayLayer::readPsfLevelStringHash() {
return true;
}

bool PSPlayLayer::readPsfVersion() {
char l_psfMagicAndVer[sizeof(s_psfMagicAndVer)];
bool PSPlayLayer::readPsfVersionAndUpdateIfNecessary() {
std::string l_psfMagicAndVer(sizeof(s_psfMagicAndVer), ' ');

m_fields->m_inputStream.read(l_psfMagicAndVer, sizeof(s_psfMagicAndVer));
if (std::strncmp(s_psfMagicAndVer, l_psfMagicAndVer, sizeof(s_psfMagicAndVer))) {
//log::info("[readPsfVersion] different version");
return false;
m_fields->m_stream.read(l_psfMagicAndVer.data(), sizeof(s_psfMagicAndVer));
l_psfMagicAndVer = l_psfMagicAndVer.substr(5, 5);
l_psfMagicAndVer.erase(std::remove(l_psfMagicAndVer.begin(), l_psfMagicAndVer.end(), '.'), l_psfMagicAndVer.end());
m_fields->m_readPsfVersion = std::stoi(l_psfMagicAndVer);
log::info("[readPsfVersion] l_psfMagicAndVer: {}", l_psfMagicAndVer);
if (s_psfVersion != m_fields->m_readPsfVersion) {
log::info("[readPsfVersion] different version");
return updatePsfFormat();
}
//log::info("[readPsfVersion] same version");
return true;
Expand All @@ -35,7 +39,7 @@ bool PSPlayLayer::readPsfVersion() {
bool PSPlayLayer::readPsfFinishedSaving() {
bool l_params[16-sizeof(s_psfMagicAndVer)];

m_fields->m_inputStream.read(reinterpret_cast<char*>(l_params), 16-sizeof(s_psfMagicAndVer));
m_fields->m_stream.read(reinterpret_cast<char*>(l_params), 16-sizeof(s_psfMagicAndVer));
if (l_params[0] == false) {
//log::info("[readPsfFinishedSaving] did not finish writing");
return false;
Expand Down Expand Up @@ -91,7 +95,7 @@ void PSPlayLayer::loadGame() {

m_fields->m_bytesToRead = std::filesystem::file_size(l_filePath);
m_fields->m_bytesRead = 0;
if(m_fields->m_bytesToRead == 0 || !m_fields->m_inputStream.setFileToRead(l_filePath, &m_fields->m_bytesRead)) {
if(m_fields->m_bytesToRead == 0 || !m_fields->m_stream.setFile(l_filePath, &m_fields->m_bytesRead)) {
m_fields->m_loadingState = LoadingState::HandleFileError;
break;
}
Expand All @@ -100,7 +104,7 @@ void PSPlayLayer::loadGame() {
// falls through
}
case LoadingState::ReadVersion: {
if (!readPsfVersion()) {
if (!readPsfVersionAndUpdateIfNecessary()) {
m_fields->m_loadingState = LoadingState::HandleIncorrectVersion;
break;
}
Expand All @@ -124,7 +128,7 @@ void PSPlayLayer::loadGame() {
// falls through
}
case LoadingState::ReadCheckpointCount: {
m_fields->m_inputStream >> m_fields->m_remainingCheckpointLoadCount;
m_fields->m_stream >> m_fields->m_remainingCheckpointLoadCount;
m_fields->m_loadingState = LoadingState::ReadCheckpoint;
// falls through
}
Expand All @@ -140,15 +144,18 @@ void PSPlayLayer::loadGame() {
}
case LoadingState::ReadActivatedCheckpoints: {
loadActivatedCheckpointsFromStream();
m_fields->m_loadingState = LoadingState::ReadTimePlayed;
m_fields->m_loadingState = LoadingState::ReadExtraData;
// falls through
}
case LoadingState::ReadTimePlayed: {
case LoadingState::ReadExtraData: {
m_fields->m_stream >> m_effectManager->m_persistentItemCountMap;
m_fields->m_stream >> m_fields->m_loadedPersistentTimerItemSet;
m_fields->m_updatePersistentTimerItemSet = true;
m_fields->m_loadingState = LoadingState::Ready;
// falls through
}
case LoadingState::Ready: {
endInputStream();
endStream();
if (m_fields->m_normalModeCheckpoints->count() > 0) {
m_fields->m_lastSavedCheckpointTimestamp = static_cast<PSCheckpointObject*>(m_fields->m_normalModeCheckpoints->lastObject())->m_fields->m_timestamp;
}
Expand Down Expand Up @@ -289,18 +296,18 @@ void PSPlayLayer::loadGame() {

void PSPlayLayer::loadActivatedCheckpointsFromStream() {
unsigned int l_size;
m_fields->m_inputStream.read(reinterpret_cast<char*>(&l_size), 4);
m_fields->m_stream.read(reinterpret_cast<char*>(&l_size), 4);
if (l_size != 0) {
m_fields->m_activatedCheckpoints.resize(l_size);
for (int i = 0; i < l_size; i++) {
m_fields->m_activatedCheckpoints[i].load(m_fields->m_inputStream);
m_fields->m_activatedCheckpoints[i].load(m_fields->m_stream);
}
}
}

void PSPlayLayer::loadCheckpointFromStream() {
PSCheckpointObject* l_checkpoint = reinterpret_cast<PSCheckpointObject*>(CheckpointObject::create());
l_checkpoint->load(m_fields->m_inputStream);
l_checkpoint->load(m_fields->m_stream);

GameObject* l_newPhysicalCPO = GameObject::createWithFrame("square_01_001.png");
CC_SAFE_RETAIN(l_newPhysicalCPO);
Expand Down Expand Up @@ -353,8 +360,4 @@ void PSPlayLayer::endAsyncProcessCreateObjectsFromSetup() {
CC_SAFE_RELEASE(m_fields->m_transitionFadeScene);
m_fields->m_transitionFadeScene = nullptr;
}
}

void PSPlayLayer::endInputStream() {
m_fields->m_inputStream.end();
}
Loading

0 comments on commit e0de697

Please sign in to comment.