aboutsummaryrefslogtreecommitdiff
path: root/builtin/game/chatcommands.lua
Commit message (Collapse)AuthorAge
* Avoid teleporting player if /teleport coords are out-of-rangetenplus12016-04-29
|
* Builtin: Add basic_privs settingrubenwardy2016-04-28
|
* Make `options` local here.Auke Kok2016-03-24
| | | | | | | | Undoubtably this may cause problems later if unchecked. ``` 2016-03-22 21:57:52: WARNING[Server]: Assignment to undeclared global "options" inside a function at .../sofar/git/minetest/bin/../builtin/game/chatcommands.lua:862. ```
* Add consistent monotonic day counter - get_day_count()Auke Kok2016-03-09
| | | | | | | | | | | | | | | | | | | | | | | | I've written several experimental bits of code that revolve around the need for a consistent calendar, but implementing one is extremely hard in mods due to time changes and mods overriding core.get_timeofday(), which will conflict. The second part of the problem is that doing this from a mod requires constant maintenance of a settings file. An implementation in core is trivial, however, and solves all of these problems at virtually no cost: No extra branches in server steps, and a single branch when minetest.set_time_of_day(), which is entirely reasonable. We store the day_count value in env_meta.txt. The use case is obvious: This change allows mods to create an actual virtual calendar, or properly account for seasonal changes, etc.. We add a "/days" chatcommand that displays the current day count. No permissions are needed. It can only retrieve the day count, not modify it.
* Faster insertion into tableRui9142016-03-06
|
* Log /clearobjects modeKahrl2016-02-11
|
* Add '/clearobjects quick'Kahrl2016-02-11
|
* Add admin command which says who the administator is for the server.Splizard2016-02-04
|
* Add callback parameter for core.emerge_area()kwolekr2015-11-02
|
* minetest. to core.Rui9142015-10-31
|
* Add /emergeblocks command and core.emerge_area() Lua APIkwolekr2015-09-23
|
* SAPI: Track last executed mod and include in error messageskwolekr2015-08-12
|
* Add ability to specify coordinates for /spawnentityMarcin2015-07-18
|
* Remove reference to deprecated privilegeCraig Davison2015-06-14
|
* Nicer time setting loggingest312015-06-02
| | | | | | | | | | Now logs ACTION[ServerThread]: player sets time to 6:03 instead of ACTION[ServerThread]: player sets time to 6:3
* Added hour:minute format to time commandLeMagnesium2015-05-16
| | | | | * The time command now accepts parameters in the form <hour>:<minute>, and if invoked with no parameters returns the current time in said format.
* Add reason to kicked log message and use present tenseest312015-04-05
|
* Radius parameter for /deleteblocks hereSmallJoker2015-03-05
|
* Add /setpassword and /clearpassword loggingest312015-02-27
|
* Fix unused (and so, broken) enable_rollback_recording. This option must be ↵Loic Blot2015-02-18
| | | | | | reloaded at server loop but loaded when server starts, for data consistency (not a hot load variable) ok @ShadowNinja
* Prevent null concatenation when /deleteblocks is provided an incorrect formatkwolekr2015-01-27
|
* Simplify deleteblocks chat command argument parsingkwolekr2015-01-15
| | | | | Add optional core.pos_to_string decimal place rounding Move core.string_to_pos to builtin/common/misc_helpers.lua for consistency
* Add ability to delete MapBlocks from mapkwolekr2015-01-15
| | | | Also add a Lua API and chatcommand for this
* Fix some undeclared global variablesCraig Davison2014-11-26
|
* Add last_login field to auth.txtRyan Newell2014-11-08
| | | | Also shortens some related code and adds more parameters to string.split.
* Add a better error message when trying to teleport another player without ↵LeMagnesium2014-10-07
| | | | bring privileges
* Mod profiling supportsapier2014-08-19
| | | | | | | | | Config settings: profiling = true/false (gather statistics) detailed_profiling = true/false (break mod times to callbacks) Chat commands: save_mod_profile saves current statistics in debug.txt and shows on console (on default loglevel)
* Add success and output return values to chat commandsShadowNinja2014-05-28
|
* Sort commands and privs alphabetically in '/help'.Diego Martinez2014-05-24
| | | | Also make a stray variable local.
* Use "core" namespace internallyShadowNinja2014-05-08
|
* Organize builtin into subdirectoriesShadowNinja2014-05-07
"hl opt">= 1 << 1, NUM_STATES = 1 << 2, STATE_INVALID = 1 << 3, }; private: std::array<bool, NUM_PROPERTIES> property_set{}; std::array<std::string, NUM_PROPERTIES> properties; State state_map = STATE_DEFAULT; public: static Property GetPropertyByName(const std::string &name) { if (name == "textcolor") { return TEXTCOLOR; } else if (name == "bgcolor") { return BGCOLOR; } else if (name == "bgcolor_hovered") { return BGCOLOR_HOVERED; } else if (name == "bgcolor_pressed") { return BGCOLOR_PRESSED; } else if (name == "noclip") { return NOCLIP; } else if (name == "border") { return BORDER; } else if (name == "bgimg") { return BGIMG; } else if (name == "bgimg_hovered") { return BGIMG_HOVERED; } else if (name == "bgimg_middle") { return BGIMG_MIDDLE; } else if (name == "bgimg_pressed") { return BGIMG_PRESSED; } else if (name == "fgimg") { return FGIMG; } else if (name == "fgimg_hovered") { return FGIMG_HOVERED; } else if (name == "fgimg_pressed") { return FGIMG_PRESSED; } else if (name == "alpha") { return ALPHA; } else if (name == "content_offset") { return CONTENT_OFFSET; } else if (name == "padding") { return PADDING; } else if (name == "font") { return FONT; } else if (name == "font_size") { return FONT_SIZE; } else if (name == "colors") { return COLORS; } else if (name == "bordercolors") { return BORDERCOLORS; } else if (name == "borderwidths") { return BORDERWIDTHS; } else if (name == "sound") { return SOUND; } else { return NONE; } } std::string get(Property prop, std::string def) const { const auto &val = properties[prop]; return val.empty() ? def : val; } void set(Property prop, const std::string &value) { properties[prop] = value; property_set[prop] = true; } //! Parses a name and returns the corresponding state enum static State getStateByName(const std::string &name) { if (name == "default") { return STATE_DEFAULT; } else if (name == "hovered") { return STATE_HOVERED; } else if (name == "pressed") { return STATE_PRESSED; } else { return STATE_INVALID; } } //! Gets the state that this style is intended for State getState() const { return state_map; } //! Set the given state on this style void addState(State state) { FATAL_ERROR_IF(state >= NUM_STATES, "Out-of-bounds state received"); state_map = static_cast<State>(state_map | state); } //! Using a list of styles mapped to state values, calculate the final // combined style for a state by propagating values in its component states static StyleSpec getStyleFromStatePropagation(const std::array<StyleSpec, NUM_STATES> &styles, State state) { StyleSpec temp = styles[StyleSpec::STATE_DEFAULT]; temp.state_map = state; for (int i = StyleSpec::STATE_DEFAULT + 1; i <= state; i++) { if ((state & i) != 0) { temp = temp | styles[i]; } } return temp; } video::SColor getColor(Property prop, video::SColor def) const { const auto &val = properties[prop]; if (val.empty()) { return def; } parseColorString(val, def, false, 0xFF); return def; } video::SColor getColor(Property prop) const { const auto &val = properties[prop]; FATAL_ERROR_IF(val.empty(), "Unexpected missing property"); video::SColor color; parseColorString(val, color, false, 0xFF); return color; } std::array<video::SColor, 4> getColorArray(Property prop, std::array<video::SColor, 4> def) const { const auto &val = properties[prop]; if (val.empty()) return def; std::vector<std::string> strs; if (!parseArray(val, strs)) return def; for (size_t i = 0; i <= 3; i++) { video::SColor color; if (parseColorString(strs[i], color, false, 0xff)) def[i] = color; } return def; } std::array<s32, 4> getIntArray(Property prop, std::array<s32, 4> def) const { const auto &val = properties[prop]; if (val.empty()) return def; std::vector<std::string> strs; if (!parseArray(val, strs)) return def; for (size_t i = 0; i <= 3; i++) def[i] = stoi(strs[i]); return def; } irr::core::rect<s32> getRect(Property prop, irr::core::rect<s32> def) const { const auto &val = properties[prop]; if (val.empty()) return def; irr::core::rect<s32> rect; if (!parseRect(val, &rect)) return def; return rect; } irr::core::rect<s32> getRect(Property prop) const { const auto &val = properties[prop]; FATAL_ERROR_IF(val.empty(), "Unexpected missing property"); irr::core::rect<s32> rect; parseRect(val, &rect); return rect; } irr::core::vector2d<s32> getVector2i(Property prop, irr::core::vector2d<s32> def) const { const auto &val = properties[prop]; if (val.empty()) return def; irr::core::vector2d<s32> vec; if (!parseVector2i(val, &vec)) return def; return vec; } irr::core::vector2d<s32> getVector2i(Property prop) const { const auto &val = properties[prop]; FATAL_ERROR_IF(val.empty(), "Unexpected missing property"); irr::core::vector2d<s32> vec; parseVector2i(val, &vec); return vec; } gui::IGUIFont *getFont() const { FontSpec spec(FONT_SIZE_UNSPECIFIED, FM_Standard, false, false); const std::string &font = properties[FONT]; const std::string &size = properties[FONT_SIZE]; if (font.empty() && size.empty()) return nullptr; std::vector<std::string> modes = split(font, ','); for (size_t i = 0; i < modes.size(); i++) { if (modes[i] == "normal") spec.mode = FM_Standard; else if (modes[i] == "mono") spec.mode = FM_Mono; else if (modes[i] == "bold") spec.bold = true; else if (modes[i] == "italic") spec.italic = true; } if (!size.empty()) { int calc_size = 1; if (size[0] == '*') { std::string new_size = size.substr(1); // Remove '*' (invalid for stof) calc_size = stof(new_size) * g_fontengine->getFontSize(spec.mode); } else if (size[0] == '+' || size[0] == '-') { calc_size = stoi(size) + g_fontengine->getFontSize(spec.mode); } else { calc_size = stoi(size); } spec.size = (unsigned)std::min(std::max(calc_size, 1), 999); } return g_fontengine->getFont(spec); } video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc, video::ITexture *def) const { const auto &val = properties[prop]; if (val.empty()) { return def; } video::ITexture *texture = tsrc->getTexture(val); return texture; } video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc) const { const auto &val = properties[prop]; FATAL_ERROR_IF(val.empty(), "Unexpected missing property"); video::ITexture *texture = tsrc->getTexture(val); return texture; } bool getBool(Property prop, bool def) const { const auto &val = properties[prop]; if (val.empty()) { return def; } return is_yes(val); } inline bool isNotDefault(Property prop) const { return !properties[prop].empty(); } inline bool hasProperty(Property prop) const { return property_set[prop]; } StyleSpec &operator|=(const StyleSpec &other) { for (size_t i = 0; i < NUM_PROPERTIES; i++) { auto prop = (Property)i; if (other.hasProperty(prop)) { set(prop, other.get(prop, "")); } } return *this; } StyleSpec operator|(const StyleSpec &other) const { StyleSpec newspec = *this; newspec |= other; return newspec; } private: bool parseArray(const std::string &value, std::vector<std::string> &arr) const { std::vector<std::string> strs = split(value, ','); if (strs.size() == 1) { arr = {strs[0], strs[0], strs[0], strs[0]}; } else if (strs.size() == 2) { arr = {strs[0], strs[1], strs[0], strs[1]}; } else if (strs.size() == 4) { arr = strs; } else { warningstream << "Invalid array size (" << strs.size() << " arguments): \"" << value << "\"" << std::endl; return false; } return true; } bool parseRect(const std::string &value, irr::core::rect<s32> *parsed_rect) const { irr::core::rect<s32> rect; std::vector<std::string> v_rect = split(value, ','); if (v_rect.size() == 1) { s32 x = stoi(v_rect[0]); rect.UpperLeftCorner = irr::core::vector2di(x, x); rect.LowerRightCorner = irr::core::vector2di(-x, -x); } else if (v_rect.size() == 2) { s32 x = stoi(v_rect[0]); s32 y = stoi(v_rect[1]); rect.UpperLeftCorner = irr::core::vector2di(x, y); rect.LowerRightCorner = irr::core::vector2di(-x, -y); // `-x` is interpreted as `w - x` } else if (v_rect.size() == 4) { rect.UpperLeftCorner = irr::core::vector2di( stoi(v_rect[0]), stoi(v_rect[1])); rect.LowerRightCorner = irr::core::vector2di( stoi(v_rect[2]), stoi(v_rect[3])); } else { warningstream << "Invalid rectangle string format: \"" << value << "\"" << std::endl; return false; } *parsed_rect = rect; return true; } bool parseVector2i(const std::string &value, irr::core::vector2d<s32> *parsed_vec) const { irr::core::vector2d<s32> vec; std::vector<std::string> v_vector = split(value, ','); if (v_vector.size() == 1) { s32 x = stoi(v_vector[0]); vec.X = x; vec.Y = x; } else if (v_vector.size() == 2) { s32 x = stoi(v_vector[0]); s32 y = stoi(v_vector[1]); vec.X = x; vec.Y = y; } else { warningstream << "Invalid vector2d string format: \"" << value << "\"" << std::endl; return false; } *parsed_vec = vec; return true; } };