diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/client.cpp | 8 | ||||
-rw-r--r-- | src/clientserver.h | 3 | ||||
-rw-r--r-- | src/content_cao.h | 3 | ||||
-rw-r--r-- | src/content_inventory.cpp | 25 | ||||
-rw-r--r-- | src/content_inventory.h | 2 | ||||
-rw-r--r-- | src/content_nodemeta.cpp | 49 | ||||
-rw-r--r-- | src/content_sao.cpp | 14 | ||||
-rw-r--r-- | src/content_sao.h | 1 | ||||
-rw-r--r-- | src/defaultsettings.cpp | 3 | ||||
-rw-r--r-- | src/environment.cpp | 42 | ||||
-rw-r--r-- | src/game.cpp | 9 | ||||
-rw-r--r-- | src/game.h | 3 | ||||
-rw-r--r-- | src/guiKeyChangeMenu.cpp | 2 | ||||
-rw-r--r-- | src/guiKeyChangeMenu.h | 2 | ||||
-rw-r--r-- | src/guiPauseMenu.cpp | 6 | ||||
-rw-r--r-- | src/inventory.cpp | 15 | ||||
-rw-r--r-- | src/inventory.h | 15 | ||||
-rw-r--r-- | src/main.cpp | 5 | ||||
-rw-r--r-- | src/server.cpp | 157 | ||||
-rw-r--r-- | src/server.h | 16 | ||||
-rw-r--r-- | src/servercommand.cpp | 11 | ||||
-rw-r--r-- | src/servercommand.h | 5 | ||||
-rw-r--r-- | src/servermain.cpp | 2 | ||||
-rw-r--r-- | src/serverobject.h | 5 | ||||
-rw-r--r-- | src/strfnd.h | 50 |
26 files changed, 373 insertions, 82 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index aae390f38..9b7ceacf1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ project(minetest-delta) set(VERSION_MAJOR 0) set(VERSION_MINOR 2) -set(VERSION_PATCH 20110720_0) +set(VERSION_PATCH 20110730_rc1) set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") # Configuration options diff --git a/src/client.cpp b/src/client.cpp index 4f0baa573..c52d3ab09 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -415,8 +415,9 @@ void Client::step(float dtime) // [0] u16 TOSERVER_INIT // [2] u8 SER_FMT_VER_HIGHEST // [3] u8[20] player_name - // [23] u8[28] password - SharedBuffer<u8> data(2+1+PLAYERNAME_SIZE+PASSWORD_SIZE); + // [23] u8[28] password (new in some version) + // [51] u16 client network protocol version (new in some version) + SharedBuffer<u8> data(2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2); writeU16(&data[0], TOSERVER_INIT); writeU8(&data[2], SER_FMT_VER_HIGHEST); @@ -428,6 +429,9 @@ void Client::step(float dtime) memset((char*)&data[23], 0, PASSWORD_SIZE); snprintf((char*)&data[23], PASSWORD_SIZE, "%s", m_password.c_str()); + + // This should be incremented in each version + writeU16(&data[51], 1); // Send as unreliable Send(0, data, false); diff --git a/src/clientserver.h b/src/clientserver.h index 35484fe76..4981b7ea8 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -171,7 +171,8 @@ enum ToServerCommand [0] u16 TOSERVER_INIT [2] u8 SER_FMT_VER_HIGHEST [3] u8[20] player_name - [23] u8[28] password + [23] u8[28] password (new in some version) + [51] u16 client network protocol version (new in some version) */ TOSERVER_INIT2 = 0x11, diff --git a/src/content_cao.h b/src/content_cao.h index b984be136..319f90380 100644 --- a/src/content_cao.h +++ b/src/content_cao.h @@ -187,7 +187,8 @@ public: core::aabbox3d<f32>* getSelectionBox() {return &m_selection_box;} v3f getPosition() - {return m_position;} + {return pos_translator.vect_show;} + //{return m_position;} private: core::aabbox3d<f32> m_selection_box; diff --git a/src/content_inventory.cpp b/src/content_inventory.cpp index 322250606..de8f8e397 100644 --- a/src/content_inventory.cpp +++ b/src/content_inventory.cpp @@ -65,6 +65,10 @@ std::string item_craft_get_image_name(const std::string &subname) return "clay_brick.png"; else if(subname == "rat") return "rat.png"; + else if(subname == "cooked_rat") + return "cooked_rat.png"; + else if(subname == "scorched_stuff") + return "scorched_stuff.png"; else if(subname == "firefly") return "firefly.png"; else @@ -98,7 +102,7 @@ s16 item_craft_get_drop_count(const std::string &subname) bool item_craft_is_cookable(const std::string &subname) { - if(subname == "lump_of_iron" || subname == "lump_of_clay") + if(subname == "lump_of_iron" || subname == "lump_of_clay" || subname == "rat" || subname == "cooked_rat") return true; return false; @@ -110,7 +114,26 @@ InventoryItem* item_craft_create_cook_result(const std::string &subname) return new CraftItem("steel_ingot", 1); else if(subname == "lump_of_clay") return new CraftItem("clay_brick", 1); + else if(subname == "rat") + return new CraftItem("cooked_rat", 1); + else if(subname == "cooked_rat") + return new CraftItem("scorched_stuff", 1); return NULL; } +bool item_craft_is_eatable(const std::string &subname) +{ + if(subname == "cooked_rat") + return true; + return false; +} + +s16 item_craft_eat_hp_change(const std::string &subname) +{ + if(subname == "cooked_rat") + return 6; // 3 hearts + return 0; +} + + diff --git a/src/content_inventory.h b/src/content_inventory.h index 0f410128b..91550bb9a 100644 --- a/src/content_inventory.h +++ b/src/content_inventory.h @@ -37,6 +37,8 @@ ServerActiveObject* item_craft_create_object(const std::string &subname, s16 item_craft_get_drop_count(const std::string &subname); bool item_craft_is_cookable(const std::string &subname); InventoryItem* item_craft_create_cook_result(const std::string &subname); +bool item_craft_is_eatable(const std::string &subname); +s16 item_craft_eat_hp_change(const std::string &subname); #endif diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp index 681e2b925..6b8bf05ef 100644 --- a/src/content_nodemeta.cpp +++ b/src/content_nodemeta.cpp @@ -277,6 +277,20 @@ bool FurnaceNodeMetadata::step(float dtime) fuel_list->decrementMaterials(1); changed = true; } + else if(ItemSpec(ITEM_MATERIAL, CONTENT_JUNGLETREE).checkItem(fuel_item)) + { + m_fuel_totaltime = 30; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_MATERIAL, CONTENT_FENCE).checkItem(fuel_item)) + { + m_fuel_totaltime = 30/2; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item)) { m_fuel_totaltime = 30/4; @@ -284,6 +298,41 @@ bool FurnaceNodeMetadata::step(float dtime) fuel_list->decrementMaterials(1); changed = true; } + else if(ItemSpec(ITEM_MATERIAL, CONTENT_BOOKSHELF).checkItem(fuel_item)) + { + m_fuel_totaltime = 30/4; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_MATERIAL, CONTENT_LEAVES).checkItem(fuel_item)) + { + m_fuel_totaltime = 30/16; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_MATERIAL, CONTENT_PAPYRUS).checkItem(fuel_item)) + { + m_fuel_totaltime = 30/32; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_MATERIAL, CONTENT_JUNGLEGRASS).checkItem(fuel_item)) + { + m_fuel_totaltime = 30/32; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_MATERIAL, CONTENT_CACTUS).checkItem(fuel_item)) + { + m_fuel_totaltime = 30/4; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } else if(ItemSpec(ITEM_CRAFT, "Stick").checkItem(fuel_item)) { m_fuel_totaltime = 30/4/4; diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 0b81855c1..638f50c9d 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -215,6 +215,18 @@ InventoryItem * ItemSAO::createInventoryItem() } } +void ItemSAO::rightClick(Player *player) +{ + dstream<<__FUNCTION_NAME<<std::endl; + InventoryItem *item = createInventoryItem(); + if(item == NULL) + return; + + bool to_be_deleted = item->use(m_env, player); + + if(to_be_deleted) + m_removed = true; +} /* RatSAO @@ -232,7 +244,7 @@ RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos): m_oldpos = v3f(0,0,0); m_last_sent_position = v3f(0,0,0); - m_yaw = 0; + m_yaw = myrand_range(0,PI*2); m_counter1 = 0; m_counter2 = 0; m_age = 0; diff --git a/src/content_sao.h b/src/content_sao.h index e5b1223d4..060c18341 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -51,6 +51,7 @@ public: std::string getStaticData(); InventoryItem* createInventoryItem(); InventoryItem* createPickedUpItem(){return createInventoryItem();} + void rightClick(Player *player); private: std::string m_inventorystring; v3f m_speed_f; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 8326a0f0d..c1104eff0 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -77,9 +77,10 @@ void set_default_settings() g_settings.setDefault("screenshot_path", "."); // Server stuff + g_settings.setDefault("motd", "<Message of the day (motd) not set>"); g_settings.setDefault("enable_experimental", "false"); g_settings.setDefault("creative_mode", "false"); - g_settings.setDefault("enable_damage", "false"); //TODO: Set to true when healing is possible + g_settings.setDefault("enable_damage", "true"); g_settings.setDefault("give_initial_stuff", "false"); g_settings.setDefault("default_password", ""); g_settings.setDefault("default_privs", "build, shout"); diff --git a/src/environment.cpp b/src/environment.cpp index d72369620..e9b94f3fa 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -816,7 +816,7 @@ void ServerEnvironment::step(float dtime) if(m_active_blocks_test_interval.step(dtime, 10.0)) { //float dtime = 10.0; - + for(core::map<v3s16, bool>::Iterator i = m_active_blocks.m_list.getIterator(); i.atEnd()==false; i++) @@ -846,6 +846,21 @@ void ServerEnvironment::step(float dtime) searching loop to keep things fast. */ // TODO: Implement usage of ActiveBlockModifier + + // Find out how many objects the block contains + u32 active_object_count = block->m_static_objects.m_active.size(); + // Find out how many objects this and all the neighbors contain + u32 active_object_count_wider = 0; + for(s16 x=-1; x<=1; x++) + for(s16 y=-1; y<=1; y++) + for(s16 z=-1; z<=1; z++) + { + MapBlock *block = m_map->getBlockNoCreateNoEx(p+v3s16(x,y,z)); + if(block==NULL) + continue; + active_object_count_wider += + block->m_static_objects.m_active.size(); + } v3s16 p0; for(p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++) @@ -875,18 +890,39 @@ void ServerEnvironment::step(float dtime) /* Convert grass into mud if under something else than air */ - else if(n.getContent() == CONTENT_GRASS) + if(n.getContent() == CONTENT_GRASS) { //if(myrand()%20 == 0) { MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0)); - if(content_features(n_top).air_equivalent == false) + if(content_features(n_top).air_equivalent == false) { n.setContent(CONTENT_MUD); m_map->addNodeWithEvent(p, n); } } } + /* + Rats spawn around regular trees + */ + if(n.getContent() == CONTENT_TREE || + n.getContent() == CONTENT_JUNGLETREE) + { + if(myrand()%200 == 0 && active_object_count_wider == 0) + { + v3s16 p1 = p + v3s16(myrand_range(-2, 2), + 0, myrand_range(-2, 2)); + MapNode n1 = m_map->getNodeNoEx(p1); + MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,-1,0)); + if(n1b.getContent() == CONTENT_GRASS && + n1.getContent() == CONTENT_AIR) + { + v3f pos = intToFloat(p1, BS); + ServerActiveObject *obj = new RatSAO(this, 0, pos); + addActiveObject(obj); + } + } + } } } } diff --git a/src/game.cpp b/src/game.cpp index b3069d6f9..6c0474ee7 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -715,7 +715,8 @@ void the_game( std::string password, std::string address, u16 port, - std::wstring &error_message + std::wstring &error_message, + std::string configpath ) { video::IVideoDriver* driver = device->getVideoDriver(); @@ -755,7 +756,7 @@ void the_game( if(address == ""){ draw_load_screen(L"Creating server...", driver, font); std::cout<<DTIME<<"Creating server"<<std::endl; - server = new Server(map_dir); + server = new Server(map_dir, configpath); server->start(port); } @@ -1656,6 +1657,8 @@ void the_game( else if(input->getRightClicked()) { std::cout<<DTIME<<"Right-clicked object"<<std::endl; + client.clickActiveObject(1, + selected_active_object->getId(), g_selected_item); } } else // selected_object == NULL @@ -2021,7 +2024,7 @@ void the_game( endscenetime_avg = endscenetime_avg * 0.95 + (float)endscenetime*0.05; char temptext[300]; - snprintf(temptext, 300, "Minetest-delta %s (" + snprintf(temptext, 300, "Minetest-c55 %s (" "R: range_all=%i" ")" " drawtime=%.0f, beginscenetime=%.0f" diff --git a/src/game.h b/src/game.h index eb289b8f2..95623316a 100644 --- a/src/game.h +++ b/src/game.h @@ -70,7 +70,8 @@ void the_game( std::string password, std::string address, u16 port, - std::wstring &error_message + std::wstring &error_message, + std::string configpath ); #endif diff --git a/src/guiKeyChangeMenu.cpp b/src/guiKeyChangeMenu.cpp index 4a11cf93c..98d6f8086 100644 --- a/src/guiKeyChangeMenu.cpp +++ b/src/guiKeyChangeMenu.cpp @@ -1,5 +1,5 @@ /* - Minetest-delta + Minetest-c55 Copyright (C) 2010-11 celeron55, Perttu Ahola <celeron55@gmail.com> Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com> Copyright (C) 2011 teddydestodes <derkomtur@schattengang.net> diff --git a/src/guiKeyChangeMenu.h b/src/guiKeyChangeMenu.h index 389ce7aee..e9e359c3c 100644 --- a/src/guiKeyChangeMenu.h +++ b/src/guiKeyChangeMenu.h @@ -1,5 +1,5 @@ /* - Minetest-delta + Minetest-c55 Copyright (C) 2010-11 celeron55, Perttu Ahola <celeron55@gmail.com> Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com> Copyright (C) 2011 teddydestodes <derkomtur@schattengang.net> diff --git a/src/guiPauseMenu.cpp b/src/guiPauseMenu.cpp index 61485518c..c704cd3fb 100644 --- a/src/guiPauseMenu.cpp +++ b/src/guiPauseMenu.cpp @@ -135,10 +135,10 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize) core::rect<s32> rect(0, 0, 180, 240);
rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2);
Environment->addStaticText(chartowchar_t(gettext(
- "Keys:\n"
+ "Default Controls:\n"
"- WASD: Walk\n"
- "- Mouse left: dig blocks\n"
- "- Mouse right: place blocks\n"
+ "- Mouse left: dig/hit\n"
+ "- Mouse right: place/use\n"
"- Mouse wheel: select item\n"
"- 0...9: select item\n"
"- Shift: sneak\n"
diff --git a/src/inventory.cpp b/src/inventory.cpp index 7ef7f0138..ca050614f 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_mapnode.h" #include "content_inventory.h" #include "content_sao.h" +#include "player.h" /* InventoryItem @@ -168,6 +169,20 @@ InventoryItem *CraftItem::createCookResult() return item_craft_create_cook_result(m_subname); } +bool CraftItem::use(ServerEnvironment *env, Player *player) +{ + if(item_craft_is_eatable(m_subname)) + { + s16 hp_change = item_craft_eat_hp_change(m_subname); + if(player->hp + hp_change > 20) + player->hp = 20; + else + player->hp += hp_change; + return true; + } + return false; +} + /* MapBlockObjectItem DEPRECATED TODO: Remove diff --git a/src/inventory.h b/src/inventory.h index 5c64f89bb..66b1cd1f0 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -37,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc., class ServerActiveObject; class ServerEnvironment; +class Player; class InventoryItem { @@ -99,12 +100,19 @@ public: /* Other properties */ + // Whether it can be cooked virtual bool isCookable(){return false;} // Time of cooking virtual float getCookTime(){return 3.0;} - // Result of cooking + // Result of cooking (can randomize) virtual InventoryItem *createCookResult(){return NULL;} + + // Eat, press, activate, whatever. + // Called when item is right-clicked when lying on ground. + // If returns true, item shall be deleted. + virtual bool use(ServerEnvironment *env, + Player *player){return false;} protected: u16 m_count; @@ -298,11 +306,16 @@ public: return 0; return QUANTITY_ITEM_MAX_COUNT - m_count; } + /* Other properties */ + bool isCookable(); InventoryItem *createCookResult(); + + bool use(ServerEnvironment *env, Player *player); + /* Special methods */ diff --git a/src/main.cpp b/src/main.cpp index da17b84bc..df0a7ff31 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1298,7 +1298,7 @@ int main(int argc, char *argv[]) g_timegetter = new SimpleTimeGetter(); // Create server - Server server(map_dir.c_str()); + Server server(map_dir.c_str(), configpath); server.start(port); // Run server @@ -1637,7 +1637,8 @@ int main(int argc, char *argv[]) password, address, port, - error_message + error_message, + configpath ); } //try diff --git a/src/server.cpp b/src/server.cpp index e2e6ce46b..07f9875c4 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1058,7 +1058,8 @@ u32 PIChecksum(core::list<PlayerInfo> &l) */ Server::Server( - std::string mapsavedir + std::string mapsavedir, + std::string configpath ): m_env(new ServerMap(mapsavedir), this), m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this), @@ -1069,6 +1070,7 @@ Server::Server( m_time_of_day_send_timer(0), m_uptime(0), m_mapsavedir(mapsavedir), + m_configpath(configpath), m_shutdown_requested(false), m_ignore_map_edit_events(false), m_ignore_map_edit_events_peer_id(0) @@ -1964,8 +1966,26 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) derr_server<<DTIME<<"Server: Cannot negotiate " "serialization version with peer " <<peer_id<<std::endl; + SendAccessDenied(m_con, peer_id, + L"Your client is too old (map format)"); return; } + + /* + Check network protocol version + */ + u16 net_proto_version = 0; + if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2) + { + net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]); + } + getClient(peer->id)->net_proto_version = net_proto_version; + /*if(net_proto_version == 0) + { + SendAccessDenied(m_con, peer_id, + L"Your client is too old (network protocol)"); + return; + }*/ /* Set up player @@ -1997,7 +2017,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) // Get password char password[PASSWORD_SIZE]; - if(datasize == 2+1+PLAYERNAME_SIZE) + if(datasize >= 2+1+PLAYERNAME_SIZE) { // old version - assume blank password password[0] = 0; @@ -2162,6 +2182,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) BroadcastChatMessage(message); } + if(getClient(peer->id)->net_proto_version == 0) + { + SendChatMessage(peer_id, L"# Server: NOTE: YOUR CLIENT IS OLD AND DOES NOT WORK PROPERLY WITH THIS SERVER"); + } + return; } @@ -2368,77 +2393,94 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) return; } + // Skip if object has been removed + if(obj->m_removed) + return; + //TODO: Check that object is reasonably close // Left click, pick object up (usually) if(button == 0) { - InventoryList *ilist = player->inventory.getList("main"); - if(g_settings.getBool("creative_mode") == false && ilist != NULL) - { + /* + Try creating inventory item + */ + InventoryItem *item = obj->createPickedUpItem(); - // Skip if inventory has no free space - if(ilist->getUsedSlots() == ilist->getSize()) + if(item) + { + InventoryList *ilist = player->inventory.getList("main"); + if(ilist != NULL) { - dout_server<<"Player inventory has no free space"<<std::endl; - return; - } + if(g_settings.getBool("creative_mode") == false) + { + // Skip if inventory has no free space + if(ilist->getUsedSlots() == ilist->getSize()) + { + dout_server<<"Player inventory has no free space"<<std::endl; + return; + } - // Skip if object has been removed - if(obj->m_removed) - return; - - /* - Create the inventory item - */ - InventoryItem *item = obj->createPickedUpItem(); - - if(item) - { - // Add to inventory and send inventory - ilist->addItem(item); - UpdateCrafting(player->peer_id); - SendInventory(player->peer_id); + // Add to inventory and send inventory + ilist->addItem(item); + UpdateCrafting(player->peer_id); + SendInventory(player->peer_id); + } // Remove object from environment obj->m_removed = true; } - else - { - /* - Item cannot be picked up. Punch it instead. - */ + } + else + { + /* + Item cannot be picked up. Punch it instead. + */ - ToolItem *titem = NULL; - std::string toolname = ""; + ToolItem *titem = NULL; + std::string toolname = ""; - InventoryList *mlist = player->inventory.getList("main"); - if(mlist != NULL) + InventoryList *mlist = player->inventory.getList("main"); + if(mlist != NULL) + { + InventoryItem *item = mlist->getItem(item_i); + if(item && (std::string)item->getName() == "ToolItem") { - InventoryItem *item = mlist->getItem(item_i); - if(item && (std::string)item->getName() == "ToolItem") - { - titem = (ToolItem*)item; - toolname = titem->getToolName(); - } + titem = (ToolItem*)item; + toolname = titem->getToolName(); } + } - v3f playerpos = player->getPosition(); - v3f objpos = obj->getBasePosition(); - v3f dir = (objpos - playerpos).normalize(); - - u16 wear = obj->punch(toolname, dir); - - if(titem) - { - bool weared_out = titem->addWear(wear); - if(weared_out) - mlist->deleteItem(item_i); - SendInventory(player->peer_id); - } + v3f playerpos = player->getPosition(); + v3f objpos = obj->getBasePosition(); + v3f dir = (objpos - playerpos).normalize(); + + u16 wear = obj->punch(toolname, dir); + + if(titem) + { + bool weared_out = titem->addWear(wear); + if(weared_out) + mlist->deleteItem(item_i); + SendInventory(player->peer_id); } } } + // Right click, do something with object + if(button == 1) + { + // Track hp changes super-crappily + u16 oldhp = player->hp; + + // Do stuff + obj->rightClick(player); + + // Send back stuff + if(player->hp != oldhp) + { + SendPlayerHP(player); + } + } } else if(command == TOSERVER_GROUND_ACTION) { @@ -3179,9 +3221,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) line += L"Server: "; message = message.substr(commandprefix.size()); + + WStrfnd f1(message); + f1.next(L" "); // Skip over /#whatever + std::wstring paramstring = f1.next(L""); ServerCommandContext *ctx = new ServerCommandContext( str_split(message, L' '), + paramstring, this, &m_env, player, @@ -4001,7 +4048,9 @@ std::wstring Server::getStatusString() } os<<L"}"; if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == false) - os<<" WARNING: Map saving is disabled."<<std::endl; + os<<std::endl<<L"# Server: "<<" WARNING: Map saving is disabled."; + if(g_settings.get("motd") != "") + os<<std::endl<<L"# Server: "<<narrow_to_wide(g_settings.get("motd")); return os.str(); } diff --git a/src/server.h b/src/server.h index 1da004da5..4a2d667a8 100644 --- a/src/server.h +++ b/src/server.h @@ -235,6 +235,8 @@ public: u16 peer_id; // The serialization version to use with the client u8 serialization_version; + // + u16 net_proto_version; // Version is stored in here after INIT before INIT2 u8 pending_serialization_version; @@ -244,6 +246,7 @@ public: { peer_id = 0; serialization_version = SER_FMT_VER_INVALID; + net_proto_version = 0; pending_serialization_version = SER_FMT_VER_INVALID; m_nearest_unsent_d = 0; m_nearest_unsent_reset_timer = 0.0; @@ -364,7 +367,8 @@ public: */ Server( - std::string mapsavedir + std::string mapsavedir, + std::string configpath ); ~Server(); void start(unsigned short port); @@ -443,6 +447,13 @@ public: dstream<<"WARNING: Auth not found for "<<name<<std::endl; } } + + // Saves g_settings to configpath given at initialization + void saveConfig() + { + if(m_configpath != "") + g_settings.updateConfigFile(m_configpath.c_str()); + } private: @@ -606,6 +617,9 @@ private: // Map directory std::string m_mapsavedir; + // Configuration path ("" = no configuration file) + std::string m_configpath; + bool m_shutdown_requested; /* diff --git a/src/servercommand.cpp b/src/servercommand.cpp index 333e29084..7d6d7bb73 100644 --- a/src/servercommand.cpp +++ b/src/servercommand.cpp @@ -142,9 +142,16 @@ void cmd_setting(std::wostringstream &os, return; } - std::string confline = wide_to_narrow(ctx->parms[1] + L" = " + ctx->parms[2]); + /*std::string confline = wide_to_narrow( + ctx->parms[1] + L" = " + ctx->params[2]);*/ + + std::string confline = wide_to_narrow(ctx->paramstring); + g_settings.parseConfigLine(confline); - os<< L"-!- Setting changed."; + + ctx->server->saveConfig(); + + os<< L"-!- Setting changed and configuration saved."; } void cmd_teleport(std::wostringstream &os, diff --git a/src/servercommand.h b/src/servercommand.h index 9013bc2a6..cee4976b1 100644 --- a/src/servercommand.h +++ b/src/servercommand.h @@ -29,6 +29,7 @@ struct ServerCommandContext { std::vector<std::wstring> parms; + std::wstring paramstring; Server* server; ServerEnvironment *env; Player* player; @@ -39,11 +40,13 @@ struct ServerCommandContext ServerCommandContext( std::vector<std::wstring> parms, + std::wstring paramstring, Server* server, ServerEnvironment *env, Player* player, u64 privs) - : parms(parms), server(server), env(env), player(player), privs(privs) + : parms(parms), paramstring(paramstring), + server(server), env(env), player(player), privs(privs) { } diff --git a/src/servermain.cpp b/src/servermain.cpp index b8fb9ba2b..dc41720fb 100644 --- a/src/servermain.cpp +++ b/src/servermain.cpp @@ -323,7 +323,7 @@ int main(int argc, char *argv[]) map_dir = g_settings.get("map-dir"); // Create server - Server server(map_dir.c_str()); + Server server(map_dir.c_str(), configpath); server.start(port); // Run server diff --git a/src/serverobject.h b/src/serverobject.h index c008bf93e..01f199a4b 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -42,6 +42,7 @@ Some planning class ServerEnvironment; class InventoryItem; +class Player; class ServerActiveObject : public ActiveObject { @@ -105,6 +106,10 @@ public: */ virtual u16 punch(const std::string &toolname, v3f dir) {return 0;} + + /* + */ + virtual void rightClick(Player *player){} /* Number of players which know about this object. Object won't be diff --git a/src/strfnd.h b/src/strfnd.h index 2be92d43b..e3d380e37 100644 --- a/src/strfnd.h +++ b/src/strfnd.h @@ -74,6 +74,56 @@ public: } }; +class WStrfnd{ + std::wstring tek; + unsigned int p; +public: + void start(std::wstring niinq){ + tek = niinq; + p=0; + } + unsigned int where(){ + return p; + } + void to(unsigned int i){ + p = i; + } + std::wstring what(){ + return tek; + } + std::wstring next(std::wstring plop){ + //std::cout<<"tek=\""<<tek<<"\" plop=\""<<plop<<"\""<<std::endl; + size_t n; + std::wstring palautus; + if (p < tek.size()) + { + //std::cout<<"\tp<tek.size()"<<std::endl; + if ((n = tek.find(plop, p)) == std::wstring::npos || plop == L"") + { + //std::cout<<"\t\tn == string::npos || plop == \"\""<<std::endl; + n = tek.size(); + } + else + { + //std::cout<<"\t\tn != string::npos"<<std::endl; + } + palautus = tek.substr(p, n-p); + p = n + plop.length(); + } + //else + //std::cout<<"\tp>=tek.size()"<<std::endl; + //std::cout<<"palautus=\""<<palautus<<"\""<<std::endl; + return palautus; + } + bool atend(){ + if(p>=tek.size()) return true; + return false; + } + WStrfnd(std::wstring s){ + start(s); + } +}; + inline std::string trim(const std::string &s) { std::string str = s; |