Compare commits

..

6 Commits

Author SHA1 Message Date
135c7dd999
Merge branch 'main' of https://github.com/OpenStarbound/OpenStarbound 2024-05-30 21:08:22 +03:00
Kae
a88b1e4ce0 sequence parsing and parseArguments fixes 2024-05-29 12:42:14 +10:00
Kae
dca7f59dbc
Merge pull request #68 from WasabiRaptor/missing-tech-check-on-player-load
Prevent crashes when player has techs that don't exist
2024-05-29 11:32:43 +10:00
Kae
465f07a9b7 fix unknown tech logging 2024-05-29 11:31:54 +10:00
Kae
3cdc8316d6 fix vertically offcenter graphicsmenu header text
[skip ci]
2024-05-29 11:10:35 +10:00
WasabiRaptor
20882990e0 error handling for missing techs 2024-05-28 10:44:34 -04:00
4 changed files with 55 additions and 35 deletions

View File

@ -42,7 +42,7 @@ function patch(config)
shift(clone(layout, "multiTextureLabel", "hardwareCursorLabel"), 98, -11).value = "HARDWARE CURSOR" shift(clone(layout, "multiTextureLabel", "hardwareCursorLabel"), 98, -11).value = "HARDWARE CURSOR"
shift(clone(layout, "multiTextureCheckbox", "hardwareCursorCheckbox"), 99, -11) shift(clone(layout, "multiTextureCheckbox", "hardwareCursorCheckbox"), 99, -11)
shift(layout.title, 0, 28) shift(layout.title, 0, 24)
shift(layout.resLabel, 0, 28) shift(layout.resLabel, 0, 28)
shift(layout.resSlider, 0, 28) shift(layout.resSlider, 0, 28)
shift(layout.resValueLabel, 0, 28) shift(layout.resValueLabel, 0, 28)

View File

@ -39,7 +39,7 @@ template <typename InputIterator>
class JsonParser { class JsonParser {
public: public:
JsonParser(JsonStream& stream) JsonParser(JsonStream& stream)
: m_line(0), m_column(0), m_stream(stream) {} : m_line(0), m_column(0), m_stream(stream), m_error(nullptr) {}
virtual ~JsonParser() {} virtual ~JsonParser() {}
// Does not throw. On error, returned iterator will not be equal to end, and // Does not throw. On error, returned iterator will not be equal to end, and
@ -65,10 +65,7 @@ public:
// Human readable parsing error, does not include line or column info. // Human readable parsing error, does not include line or column info.
char const* error() const { char const* error() const {
if (m_error.empty()) return m_error;
return nullptr;
else
return m_error.c_str();
} }
size_t line() const { size_t line() const {
@ -216,31 +213,42 @@ private:
break; break;
else { else {
auto begin = m_current; auto begin = m_current;
auto b_char = m_char;
if (m_char >= '0' && m_char <= '9') { if (m_char >= '0' && m_char <= '9') {
number(); try {
if (m_error.empty()) { number(true);
}
catch (ParsingException const&) {
m_current = begin;
m_char = b_char;
}
if (m_error == nullptr) {
next(); next();
continue; continue;
} }
} }
m_error.clear(); m_error = nullptr;
m_current = begin;
if (m_char == 't' || m_char == 'f' || m_char == 'n') { if (m_char == 't' || m_char == 'f' || m_char == 'n') {
word(); try {
if (m_error.empty()) { word(true);
}
catch (ParsingException const&) {
m_current = begin;
m_char = b_char;
}
if (m_error == nullptr) {
next(); next();
continue; continue;
} }
} }
m_error.clear(); m_error = nullptr;
m_current = begin;
// well, shit. do a simple string parse until we hit whitespace // well, shit. do a simple string parse until we hit whitespace
// no fancy things like \n, do a proper string if you want that // no fancy things like \n, do a proper string if you want that
CharArray str; CharArray str;
do { do {
str += m_char; str += m_char;
next(); next();
} while (m_char && !isSpace(m_char)); } while (m_char != 0 && !isSpace(m_char));
m_stream.putString(str.c_str(), str.length()); m_stream.putString(str.c_str(), str.length());
} }
next(); next();
@ -253,7 +261,7 @@ private:
m_stream.putString(s.c_str(), s.length()); m_stream.putString(s.c_str(), s.length());
} }
void number() { void number(bool seq = false) {
std::basic_string<char32_t> buffer; std::basic_string<char32_t> buffer;
bool isDouble = false; bool isDouble = false;
@ -298,29 +306,34 @@ private:
} }
} }
if (seq && m_char != 0 && !isSpace(m_char))
error("unexpected character after number");
if (isDouble) { if (isDouble) {
try { try {
m_stream.putDouble(buffer.c_str(), buffer.length()); m_stream.putDouble(buffer.c_str(), buffer.length());
} catch (std::exception const& e) { } catch (std::exception const& e) {
error(std::string("Bad double: ") + e.what()); error("bad double");
} }
} else { } else {
try { try {
m_stream.putInteger(buffer.c_str(), buffer.length()); m_stream.putInteger(buffer.c_str(), buffer.length());
} catch (std::exception const& e) { } catch (std::exception const& e) {
error(std::string("Bad integer: ") + e.what()); error("bad integer");
} }
} }
} }
// true, false, or null // true, false, or null
void word() { void word(bool seq = false) {
switch (m_char) { switch (m_char) {
case 't': case 't':
next(); next();
check('r'); check('r');
check('u'); check('u');
check('e'); check('e');
if (seq && m_char != 0 && !isSpace(m_char))
error("unexpected character after word");
m_stream.putBoolean(true); m_stream.putBoolean(true);
break; break;
case 'f': case 'f':
@ -329,6 +342,8 @@ private:
check('l'); check('l');
check('s'); check('s');
check('e'); check('e');
if (seq && m_char != 0 && !isSpace(m_char))
error("unexpected character after word");
m_stream.putBoolean(false); m_stream.putBoolean(false);
break; break;
case 'n': case 'n':
@ -336,6 +351,8 @@ private:
check('u'); check('u');
check('l'); check('l');
check('l'); check('l');
if (seq && m_char != 0 && !isSpace(m_char))
error("unexpected character after word");
m_stream.putNull(); m_stream.putNull();
break; break;
default: default:
@ -502,24 +519,22 @@ private:
} }
} else { } else {
// The only allowed characters following / in whitespace are / and * // The only allowed characters following / in whitespace are / and *
error("/ character in whitespace is not follwed by '/' or '*', invalid comment"); error("/ character in whitespace is not followed by '/' or '*', invalid comment");
return; return;
} }
} else if (isSpace(m_char)) { } else if (isSpace(m_char)) {
buffer += m_char; buffer += m_char;
next(); next();
} else { } else {
if (buffer.size() != 0) break;
m_stream.putWhitespace(buffer.c_str(), buffer.length());
return;
} }
} }
if (buffer.size() != 0) if (buffer.size() != 0)
m_stream.putWhitespace(buffer.c_str(), buffer.length()); m_stream.putWhitespace(buffer.c_str(), buffer.length());
} }
void error(std::string msg) { void error(const char* msg) {
m_error = std::move(msg); m_error = msg;
throw ParsingException(); throw ParsingException();
} }
@ -537,7 +552,7 @@ private:
InputIterator m_end; InputIterator m_end;
size_t m_line; size_t m_line;
size_t m_column; size_t m_column;
std::string m_error; const char* m_error;
JsonStream& m_stream; JsonStream& m_stream;
}; };

View File

@ -61,8 +61,8 @@ LuaCallbacks LuaBindings::makeChatCallbacks(MainInterface* mainInterface, Univer
}); });
// just for SE compat - this shoulda been a utility callback :moyai: // just for SE compat - this shoulda been a utility callback :moyai:
callbacks.registerCallback("parseArguments", [](String const& args) { callbacks.registerCallback("parseArguments", [](String const& args) -> LuaVariadic<Json> {
return Json::parseSequence(args); return Json::parseSequence(args).toArray();
}); });
callbacks.registerCallback("command", [mainInterface](String const& command) -> StringList { callbacks.registerCallback("command", [mainInterface](String const& command) -> StringList {

View File

@ -9,9 +9,14 @@ PlayerTech::PlayerTech() {}
PlayerTech::PlayerTech(Json const& json) { PlayerTech::PlayerTech(Json const& json) {
m_availableTechs = jsonToStringSet(json.get("availableTechs")); m_availableTechs = jsonToStringSet(json.get("availableTechs"));
m_enabledTechs = jsonToStringSet(json.get("enabledTechs")); m_enabledTechs = jsonToStringSet(json.get("enabledTechs"));
m_equippedTechs = jsonToMapKV<HashMap<TechType, String>>(json.get("equippedTechs"), [](Json t) { auto techDatabase = Root::singleton().techDatabase();
return TechTypeNames.getLeft(t.toString()); for (auto& p : json.getObject("equippedTechs")) {
}, mem_fn(&Json::toString)); String techName = p.second.toString();
if (techDatabase->contains(techName))
m_equippedTechs.set(TechTypeNames.getLeft(p.first), techName);
else
Logger::warn("Unequipping unknown tech '{}' from slot '{}'", techName, p.first);
}
} }
Json PlayerTech::toJson() const { Json PlayerTech::toJson() const {