diff --git a/CMakeLists.txt b/CMakeLists.txt index bc8c73d..7a4f3dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string") # Also remember to set PROTOCOL_VERSION in clientserver.h when releasing set(VERSION_MAJOR 0) set(VERSION_MINOR 1) -set(VERSION_PATCH dev-20120430) +set(VERSION_PATCH dev-20120501) if(VERSION_EXTRA) set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA}) endif() diff --git a/src/client.cpp b/src/client.cpp index 09e946c..437739b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1378,6 +1378,12 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) u8 oxygen = readU8(is); player->oxygen = oxygen; } + else if(command == TOCLIENT_KICK) + { + ClientEvent event; + event.type = CE_KICKED; + m_client_event_queue.push_back(event); + } else if(command == TOCLIENT_MOVE_PLAYER) { std::string datastring((char*)&data[2], datasize-2); diff --git a/src/client.h b/src/client.h index a9e9178..8e58c6e 100644 --- a/src/client.h +++ b/src/client.h @@ -133,6 +133,7 @@ enum ClientEventType CE_NONE, CE_PLAYER_DAMAGE, CE_PLAYER_FORCE_MOVE, + CE_KICKED, CE_DEATHSCREEN, CE_TEXTURES_UPDATED }; diff --git a/src/clientserver.h b/src/clientserver.h index 36ee619..fd7c86c 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -316,6 +316,11 @@ enum ToClientCommand u16 command u8 oxygen */ + + TOCLIENT_KICK = 0x44, + /* + u16 command + */ }; enum ToServerCommand diff --git a/src/game.cpp b/src/game.cpp index 15ae55d..594c2ec 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2125,6 +2125,10 @@ void the_game( camera_yaw = event.player_force_move.yaw; camera_pitch = event.player_force_move.pitch; } + else if(event.type == CE_KICKED) + { + g_gamecallback->disconnect(); + } else if(event.type == CE_DEATHSCREEN) { if(respawn_menu_active) diff --git a/src/server.cpp b/src/server.cpp index b0cdd21..85a77d0 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3472,6 +3472,20 @@ void Server::SendOxygen(con::Connection &con, u16 peer_id, u8 oxygen) con.Send(peer_id, 0, data, true); } +void Server::SendKick(con::Connection &con, u16 peer_id) +{ + DSTACK(__FUNCTION_NAME); + std::ostringstream os(std::ios_base::binary); + + writeU16(os, TOCLIENT_KICK); + + // Make data buffer + std::string s = os.str(); + SharedBuffer data((u8*)s.c_str(), s.size()); + // Send as reliable + con.Send(peer_id, 0, data, true); +} + void Server::SendAccessDenied(con::Connection &con, u16 peer_id, const std::wstring &reason) @@ -3663,6 +3677,14 @@ void Server::SendPlayerOxygen(u16 peer_id) SendOxygen(m_con, peer_id, playersao->getOxygen()); } +void Server::SendPlayerKick(u16 peer_id) +{ + DSTACK(__FUNCTION_NAME); + PlayerSAO *playersao = getPlayerSAO(peer_id); + assert(playersao); + SendKick(m_con, peer_id); +} + void Server::SendMovePlayer(u16 peer_id) { DSTACK(__FUNCTION_NAME); diff --git a/src/server.h b/src/server.h index a73ee46..2a1c891 100644 --- a/src/server.h +++ b/src/server.h @@ -558,6 +558,7 @@ public: std::string getWorldPath(){ return m_path_world; } bool isSingleplayer(){ return m_simple_singleplayer_mode; } + void SendPlayerKick(u16 peer_id); void setAsyncFatalError(const std::string &error) { @@ -579,6 +580,7 @@ private: static void SendHP(con::Connection &con, u16 peer_id, u8 hp); static void SendHunger(con::Connection &con, u16 peer_id, u8 hunger); static void SendOxygen(con::Connection &con, u16 peer_id, u8 oxygen); + static void SendKick(con::Connection &con, u16 peer_id); static void SendAccessDenied(con::Connection &con, u16 peer_id, const std::wstring &reason); static void SendDeathscreen(con::Connection &con, u16 peer_id, diff --git a/src/servercommand.cpp b/src/servercommand.cpp index cf89f7f..4ad87d5 100644 --- a/src/servercommand.cpp +++ b/src/servercommand.cpp @@ -79,6 +79,33 @@ void cmd_shutdown(std::wostringstream &os, ctx->flags |= SEND_TO_OTHERS; } +void cmd_kick(std::wostringstream &os, ServerCommandContext *ctx) +{ + if(!ctx->server->checkPriv(ctx->player->getName(), "basic_privs") && + !ctx->server->checkPriv(ctx->player->getName(), "privs")) + { + os<parms.size() < 2) + { + os<env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str()); + if(player == NULL) + { + os<getName(); + } + else + { + ctx->server->SendPlayerKick(player->peer_id); + os<getName(); + } + } +} + void cmd_banunban(std::wostringstream &os, ServerCommandContext *ctx) { if(!ctx->server->checkPriv(ctx->player->getName(), "ban")) @@ -99,7 +126,7 @@ void cmd_banunban(std::wostringstream &os, ServerCommandContext *ctx) if(player == NULL) { - os<getName(); return; } @@ -171,6 +198,8 @@ std::wstring processServerCommand(ServerCommandContext *ctx) cmd_time(os, ctx); else if(ctx->parms[0] == L"shutdown") cmd_shutdown(os, ctx); + else if(ctx->parms[0] == L"kick") + cmd_kick(os, ctx); else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban") cmd_banunban(os, ctx); else if(ctx->parms[0] == L"me")