diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj
index b077e9c0..6c8e0197 100644
--- a/Crawler/Crawler.vcxproj
+++ b/Crawler/Crawler.vcxproj
@@ -300,6 +300,7 @@
+
diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters
index 7da615e8..9babdce1 100644
--- a/Crawler/Crawler.vcxproj.filters
+++ b/Crawler/Crawler.vcxproj.filters
@@ -402,6 +402,9 @@
Header Files
+
+ Header Files
+
diff --git a/Crawler/LoadFileButton.h b/Crawler/LoadFileButton.h
index c0582e1e..fc16e6cb 100644
--- a/Crawler/LoadFileButton.h
+++ b/Crawler/LoadFileButton.h
@@ -64,7 +64,7 @@ public:
animationTime+=game->GetElapsedTime();
}
- inline void DrawDecal(ViewPort&window,bool focused){
+ inline void DrawDecal(ViewPort&window,bool focused)override{
MenuComponent::DrawDecal(window,focused);
if(playTime==-1){
diff --git a/Crawler/MainMenuWindow.cpp b/Crawler/MainMenuWindow.cpp
index d74814a8..8f990219 100644
--- a/Crawler/MainMenuWindow.cpp
+++ b/Crawler/MainMenuWindow.cpp
@@ -48,10 +48,10 @@ void Menu::InitializeMainMenuWindow(){
Menu*mainMenuWindow=CreateMenu(MAIN_MENU,CENTERED,vi2d{96,96});
mainMenuWindow->ADD("New Game Button",MenuComponent)({{12,4},{72,24}},"New Game",[&](MenuFuncData data){
+ game->TextEntryEnable(true);
#ifdef __EMSCRIPTEN__
data.menu.S(A::NEXT_MENU)="New Game";
if(SaveFile::GetUserID().length()==0){
- game->TextEntryEnable(true);
Menu::OpenMenu(USER_ID);
}else{
Menu::OpenMenu(SAVE_FILE_NAME);
diff --git a/Crawler/MenuComponent.cpp b/Crawler/MenuComponent.cpp
index cb81c8a4..384d48b4 100644
--- a/Crawler/MenuComponent.cpp
+++ b/Crawler/MenuComponent.cpp
@@ -195,7 +195,7 @@ const vf2d&MenuComponent::GetSize()const{
return rect.size;
}
-std::string MenuComponent::GetLabel(){
+const std::string&MenuComponent::GetLabel()const{
return label;
}
diff --git a/Crawler/MenuComponent.h b/Crawler/MenuComponent.h
index 24b03b81..72fa287c 100644
--- a/Crawler/MenuComponent.h
+++ b/Crawler/MenuComponent.h
@@ -142,7 +142,7 @@ public:
virtual bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton);
//Called whenever equipment and base stats are updated, notifying a component that numbers that may be displayed have changed.
virtual void OnEquipStatsUpdate();
- std::string GetLabel();
+ virtual const std::string&GetLabel()const;
std::string GetName();
virtual void SetSelected(bool selected)final;
virtual void SetSelectionType(SelectionType selectionType)final;
diff --git a/Crawler/SaveFile.cpp b/Crawler/SaveFile.cpp
index b95f1e4b..6878d38b 100644
--- a/Crawler/SaveFile.cpp
+++ b/Crawler/SaveFile.cpp
@@ -209,7 +209,25 @@ const std::string SaveFile::CreateServerRequest(const SaveFileOperation::Operati
auto CalculateChecksum=[](std::string_view operation,std::string_view data){
return username.length()*8+data.length()*2+operation.length();
};
- std::string dataString=std::format("?username={}",username);
+ auto EncodeURI=[](std::string str){
+ return std::accumulate(str.begin(),str.end(),""s,[](std::string str,const char&c){
+ /*
+ * Implementation Source: https://262.ecma-international.org/5.1/#sec-15.1.3.4
+ uriReserved ::: one of
+ ; / ? : @ & = + $ ,
+ uriMark ::: one of
+ - _ . ! ~ * ' ( )
+ Let unescapedURISet be a String containing one instance of each character valid in uriReserved and uriUnescaped plus “#”.
+ */
+ const std::array uriReserved={';','/','?',':','@','&','=','+','$',',','-','_','.','!','~','*','\'','(',')','#'};
+ if(c>='A'&&c<='Z'||c>='a'&&c<='z'||c>='0'&&c<='9'||std::find(uriReserved.begin(),uriReserved.end(),c)!=uriReserved.end())return std::move(str)+c;
+
+ std::string convertedChar=std::format("%{:02x}",c);
+ std::for_each(convertedChar.begin(),convertedChar.end(),[](char&c){c=char(std::toupper(c));});
+ return std::move(str)+convertedChar;
+ });
+ };
+ std::string dataString=std::format("\"username\":\"{}\"",EncodeURI(username));
std::string operationName="";
switch(operation){
case SaveFileOperation::GET_LOAD_FILES:{
@@ -229,35 +247,41 @@ const std::string SaveFile::CreateServerRequest(const SaveFileOperation::Operati
//Data should contain the entire contents of our metadata save file.
}break;
}
- dataString+="&operation="+operationName;
- dataString+="&checksum="+std::to_string(CalculateChecksum(operationName,data));
- dataString+="&data="+std::string(data);
- return "save_server"_S+dataString;
+ dataString+=",\"operation\":\""+EncodeURI(operationName)+"\"";
+ dataString+=",\"checksum\":\""+EncodeURI(std::to_string(CalculateChecksum(operationName,data)))+"\"";
+ dataString+=",\"data\":\""+EncodeURI(std::string(data))+"\"";
+ return "{"+dataString+"}";
}
const void SaveFile::Server_GetLoadInfo(std::functionrespCallbackFunc){
- game->SendRequest(CreateServerRequest(SaveFileOperation::GET_LOAD_FILES,"0"),"");
+ game->SendRequest("save_server"_S,CreateServerRequest(SaveFileOperation::GET_LOAD_FILES,"0"));
game->responseCallback=respCallbackFunc;
}
const void SaveFile::Server_GetFile(std::functionrespCallbackFunc){
- game->SendRequest(CreateServerRequest(SaveFileOperation::GET_FILE,std::to_string(saveFileID)),"");
+ game->SendRequest("save_server"_S,CreateServerRequest(SaveFileOperation::GET_FILE,std::to_string(saveFileID)));
game->responseCallback=respCallbackFunc;
}
const void SaveFile::Server_SaveFile(std::functionrespCallbackFunc){
std::stringstream fileContents;
std::ifstream file("save_file_path"_S+std::format("save.{:04}",saveFileID));
while(file.good()){
- fileContents<SendRequest(CreateServerRequest(SaveFileOperation::SAVE_FILE,std::to_string(saveFileID)+"|"+fileContents.str()),"");
+ game->SendRequest("save_server"_S,CreateServerRequest(SaveFileOperation::SAVE_FILE,std::to_string(saveFileID)+"|"+fileContents.str()));
game->responseCallback=respCallbackFunc;
}
const void SaveFile::Server_SaveMetadataFile(std::functionrespCallbackFunc){
std::stringstream fileContents;
std::ifstream file("save_file_path"_S+"metadata.dat");
while(file.good()){
- fileContents<SendRequest(CreateServerRequest(SaveFileOperation::SAVE_METADATA_FILE,fileContents.str()),"");
+ game->SendRequest("save_server"_S,CreateServerRequest(SaveFileOperation::SAVE_METADATA_FILE,fileContents.str()));
game->responseCallback=respCallbackFunc;
}
diff --git a/Crawler/TextEntryLabel.h b/Crawler/TextEntryLabel.h
index 3dfe85d3..474fc9f7 100644
--- a/Crawler/TextEntryLabel.h
+++ b/Crawler/TextEntryLabel.h
@@ -76,4 +76,12 @@ public:
}
}
}
+
+ inline const std::string&GetLabel()const override{
+ if(censored){
+ return game->TextEntryGetString();
+ }else{
+ MenuLabel::GetLabel();
+ }
+ }
};
\ No newline at end of file
diff --git a/Crawler/Version.h b/Crawler/Version.h
index b85e0cb4..a0e20a47 100644
--- a/Crawler/Version.h
+++ b/Crawler/Version.h
@@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
-#define VERSION_BUILD 5287
+#define VERSION_BUILD 5293
#define stringify(a) stringify_(a)
#define stringify_(a) #a
diff --git a/Crawler/olcPixelGameEngine.h b/Crawler/olcPixelGameEngine.h
index d10b1f70..5c4384b1 100644
--- a/Crawler/olcPixelGameEngine.h
+++ b/Crawler/olcPixelGameEngine.h
@@ -1205,7 +1205,7 @@ namespace olc
// Text Entry Routines
void TextEntryEnable(const bool bEnable, const std::string& sText = "");
- std::string TextEntryGetString() const;
+ const std::string&TextEntryGetString() const;
int32_t TextEntryGetCursor() const;
bool IsTextEntryEnabled() const;
void TextEntrySetCharLimit(const uint8_t charLimit);
@@ -4294,7 +4294,7 @@ namespace olc
}
}
- std::string PixelGameEngine::TextEntryGetString() const
+ const std::string&PixelGameEngine::TextEntryGetString() const
{ return sTextEntryString; }
int32_t PixelGameEngine::TextEntryGetCursor() const
@@ -7217,14 +7217,18 @@ namespace olc
virtual olc::rcode SendRequest(std::string_view url,std::string_view data)override{
EM_ASM({
requestResp="";
- fetch(UTF8ToString($0)).then((resp)=>{
+ fetch(UTF8ToString($0),{
+ headers: {
+ "Content-Type": "application/json",
+ },
+ method: "POST",body:UTF8ToString($1)}).then((resp)=>{
if(resp.ok){
resp.text();
}
throw new Error(resp.text());
}).then((data)=>{requestResp=data;})
.catch((err)=>{requestResp="ERR";});
- },std::string(url).c_str());
+ },std::string(url).c_str(),std::string(data).c_str());
return olc::rcode::OK;
}