From 1be398319c0f2ef8342cc42f3d6f6d9011652ff7 Mon Sep 17 00:00:00 2001 From: Misa Date: Thu, 20 Feb 2020 09:43:52 -0800 Subject: [PATCH] Make `commands`, `sb`, and `hooklist` not use separate length-trackers This is a refactor that turns the script-related arrays `ed.sb`, and `ed.hooklist` into C++ vectors (`script.commands` was already a vector, it was just misused). The code handling these vectors now looks more like idiomatic C++ than sloppily-pasted pseudo-ActionScript. This removes the variables `script.scriptlength`, `ed.sblength`, and `ed.numhooks`, too. This reduces the amount of code needed to e.g. simply remove something from any of these vectors. Previously the code had to manually shift the rest of the elements down one-by-one, and doing it manually is definitely error-prone and tedious. But now we can just use fancy functions like `std::vector::erase()` and `std::remove()` to do it all in one line! Don't worry, I checked and `std::remove()` is in the C++ standard since at least 1998. This patch makes it so the `commands` vector gets cleared when `scriptclass::load()` is ran. Previously, the `commands` vector never actually properly got cleared, so there could potentially be glitches that rely on the game indexing past the bounds set by `scriptlength` but still in-bounds in the eyes of C++, and people could potentially rely on such an exploit... However, I checked, and I'm pretty sure that no such glitch previously existed at all, because the only times the vector gets indexed are when `scriptlength` is either being incremented after starting from 0 (`add()`) or when it's underneath a `position < scriptlength` conditional. Furthermore, I'm unaware of anyone who has actually found or used such an exploit, and I've been in the custom level community for 6 years. So I think it's fine. --- desktop_version/src/Script.cpp | 6 +- desktop_version/src/Script.h | 5 +- desktop_version/src/Scripts.cpp | 2 +- desktop_version/src/editor.cpp | 123 ++++++++++---------------------- desktop_version/src/editor.h | 6 +- 5 files changed, 43 insertions(+), 99 deletions(-) diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp index a05978f9..ac14e83c 100644 --- a/desktop_version/src/Script.cpp +++ b/desktop_version/src/Script.cpp @@ -11,12 +11,10 @@ scriptclass::scriptclass() //Start SDL //Init - commands.resize(500); words.resize(40); txt.resize(40); position = 0; - scriptlength = 0; scriptdelay = 0; running = false; @@ -72,7 +70,7 @@ void scriptclass::run( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, { while(running && scriptdelay<=0 && !game.pausescript) { - if (position < scriptlength) + if (position < (int) commands.size()) { //Let's split or command in an array of words tokenize(commands[position]); @@ -3596,7 +3594,7 @@ void scriptclass::hardreset( KeyPoll& key, Graphics& dwgfx, Game& game,mapclass& //Script Stuff position = 0; - scriptlength = 0; + commands.clear(); scriptdelay = 0; scriptname = "null"; running = false; diff --git a/desktop_version/src/Script.h b/desktop_version/src/Script.h index 29b36a19..e4e3a403 100644 --- a/desktop_version/src/Script.h +++ b/desktop_version/src/Script.h @@ -23,8 +23,7 @@ public: void inline add(std::string t) { - commands[scriptlength] = t; - scriptlength++; + commands.push_back(t); } void clearcustom(); @@ -51,7 +50,7 @@ public: std::vector words; std::vector txt; std::string scriptname; - int position, scriptlength; + int position; int looppoint, loopcount; int scriptdelay; diff --git a/desktop_version/src/Scripts.cpp b/desktop_version/src/Scripts.cpp index 771dfec9..f47a6297 100644 --- a/desktop_version/src/Scripts.cpp +++ b/desktop_version/src/Scripts.cpp @@ -11,7 +11,7 @@ void scriptclass::load(std::string t) { //loads script name t into the array position = 0; - scriptlength=0; + commands.clear(); running = true; int maxlength = (std::min(int(t.length()),7)); diff --git a/desktop_version/src/editor.cpp b/desktop_version/src/editor.cpp index 386f0b6d..e8c0a349 100644 --- a/desktop_version/src/editor.cpp +++ b/desktop_version/src/editor.cpp @@ -324,25 +324,11 @@ void editorclass::reset() } } - if(numhooks>0) - { - for(int i=0; i1) sblength--; + if(sb.empty()) + { + //Always have one line or we'll have problems + sb.resize(1); + } } void editorclass::addhooktoscript(std::string t) @@ -440,12 +427,9 @@ void editorclass::addhooktoscript(std::string t) //Adds hook+the scriptbuffer to the end of the scriptclass removehookfromscript(t); script.customscript.push_back(t+":"); - if(sblength>=1) + for(size_t i=0; i1) + if((int)sb.size()>1) { - if(sblength==t) - { - sblength--; - } - else - { - for(int i=t; i=t; i--) - { - sb[i+1]=sb[i]; - } - sb[t]=""; - sblength++; + sb.insert(sb.begin() + t, ""); } void editorclass::loadlevel( int rxi, int ryi ) @@ -2912,21 +2862,21 @@ void editorrender( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, ent dwgfx.Print(16,44,"PRESS ESC TO RETURN TO MENU", 123, 111, 218, true); //dwgfx.Print(16,60,"READY.", 123, 111, 218, false); - if(ed.numhooks>0) + if(!ed.hooklist.empty()) { for(int i=0; i<9; i++) { - if(ed.hookmenupage+i0) @@ -3718,9 +3668,9 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti ed.hookmenu++; } - if(ed.hookmenu>=ed.numhooks) + if(ed.hookmenu>=(int)ed.hooklist.size()) { - ed.hookmenu=ed.numhooks-1; + ed.hookmenu=ed.hooklist.size()-1; } if(ed.hookmenu<0) ed.hookmenu=0; @@ -3740,7 +3690,7 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti { ed.deletekeyheld=1; music.playef(2); - ed.removehook(ed.hooklist[(ed.numhooks-1)-ed.hookmenu]); + ed.removehook(ed.hooklist[(ed.hooklist.size()-1)-ed.hookmenu]); } if (!game.press_action && !game.press_left && !game.press_right @@ -3752,15 +3702,15 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti { game.jumpheld = true; } - if ((game.press_action || game.press_map) && ed.numhooks>0) + if ((game.press_action || game.press_map) && !ed.hooklist.empty()) { game.mapheld=true; ed.scripthelppage=1; key.keybuffer=""; - ed.sbscript=ed.hooklist[(ed.numhooks-1)-ed.hookmenu]; + ed.sbscript=ed.hooklist[(ed.hooklist.size()-1)-ed.hookmenu]; ed.loadhookineditor(ed.sbscript); - ed.sby=ed.sblength-1; + ed.sby=ed.sb.size()-1; ed.pagey=0; while(ed.sby>=20) { @@ -3813,7 +3763,7 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti if(key.keymap[SDLK_DOWN] && ed.keydelay<=0) { ed.keydelay=6; - if(ed.sby+ed.pagey=20) @@ -3862,7 +3812,7 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti { game.mapheld=true; //Continue to next line - if(ed.sby+ed.pagey>=ed.sblength) //we're on the last line + if(ed.sby+ed.pagey>=(int)ed.sb.size()) //we're on the last line { ed.sby++; if(ed.sby>=20) @@ -3870,7 +3820,6 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti ed.pagey++; ed.sby--; } - if(ed.sby+ed.pagey>=ed.sblength) ed.sblength=ed.sby+ed.pagey; key.keybuffer=ed.sb[ed.pagey+ed.sby]; ed.sbx = utf8::unchecked::distance(ed.sb[ed.pagey+ed.sby].begin(), ed.sb[ed.pagey+ed.sby].end()); } diff --git a/desktop_version/src/editor.h b/desktop_version/src/editor.h index 595d62c1..5ac8b451 100644 --- a/desktop_version/src/editor.h +++ b/desktop_version/src/editor.h @@ -207,9 +207,8 @@ class editorclass{ bool scripteditmod; int scripthelppage, scripthelppagedelay; - std::string sb[500]; + std::vector sb; std::string sbscript; - int sblength; int sbx, sby; int pagey; @@ -226,8 +225,7 @@ class editorclass{ void clearscriptbuffer(); void gethooks(); bool checkhook(std::string t); - std::string hooklist[500]; - int numhooks; + std::vector hooklist; int hookmenupage, hookmenu;