From acb87fa22525df21c416466ae07f3fd12a80f0a1 Mon Sep 17 00:00:00 2001 From: HarpyWar <harpywar@gmail.com> Date: Sun, 4 May 2014 00:57:05 +0400 Subject: [PATCH] - add "config" table for Lua scripts with all the options from bnetd.conf - all Lua functions are in "api" lib - extract Lua functions, and objects into different cpp files --- src/bnetd/luafunctions.cpp | 561 +++++++++++++++++++ src/bnetd/luafunctions.h | 52 ++ src/bnetd/luainterface.cpp | 1059 ++++++------------------------------ src/bnetd/luainterface.h | 12 +- src/bnetd/luaobjects.cpp | 363 ++++++++++++ src/bnetd/luaobjects.h | 54 ++ 6 files changed, 1198 insertions(+), 903 deletions(-) create mode 100644 src/bnetd/luafunctions.cpp create mode 100644 src/bnetd/luafunctions.h create mode 100644 src/bnetd/luaobjects.cpp create mode 100644 src/bnetd/luaobjects.h diff --git a/src/bnetd/luafunctions.cpp b/src/bnetd/luafunctions.cpp new file mode 100644 index 0000000..21ec59e --- /dev/null +++ b/src/bnetd/luafunctions.cpp @@ -0,0 +1,561 @@ +/* +* Copyright (C) 2014 HarpyWar (harpywar@gmail.com) +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "common/setup_before.h" +#define GAME_INTERNAL_ACCESS + +#include <cctype> +#include <cerrno> +#include <cstring> +#include <cstdlib> + + +#include "compat/strcasecmp.h" +#include "compat/snprintf.h" +#include "common/tag.h" +#include "common/util.h" +#include "common/eventlog.h" +#include "common/list.h" +#include "common/hashtable.h" + +#include "connection.h" +#include "message.h" +#include "channel.h" +#include "game.h" +#include "account.h" +#include "account_wrap.h" +#include "timer.h" +#include "ipban.h" +#include "command_groups.h" +#include "friends.h" +#include "clan.h" +#include "attrlayer.h" + +#include "luawrapper.h" +#include "luaobjects.h" + +#include "common/setup_after.h" + + +namespace pvpgn +{ + + namespace bnetd + { + + typedef enum { + attr_type_str, + attr_type_num, + attr_type_bool, + attr_type_raw + } t_attr_type; + + + /* Send message text to user */ + extern int __message_send_text(lua_State* L) + { + const char *text; + const char *username_src, *username_dst; + int message_type; + t_connection *c_src = NULL, *c_dst = NULL; + + try + { + lua::stack st(L); + // get args + st.at(1, username_dst); + st.at(2, message_type); + st.at(3, username_src); + st.at(4, text); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + + // get user connections + if (t_account * account = accountlist_find_account(username_dst)) + c_dst = account_get_conn(account); + + if (username_src) + if (t_account * account = accountlist_find_account(username_src)) + c_src = account_get_conn(account); + + // send message + // (source can be NULL, but destination cant) + if (c_dst) + message_send_text(c_dst, (t_message_type)message_type, c_src, text); + + return 0; + } + + /* Log text into logfile */ + extern int __eventlog(lua_State* L) + { + int loglevel; + const char *text, *function; + + try + { + lua::stack st(L); + // get args + st.at(1, loglevel); + st.at(2, function); + st.at(3, text); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + eventlog(t_eventlog_level(loglevel), function, text); + + return 0; + } + + /* Get one account table object */ + extern int __account_get_by_name(lua_State* L) + { + const char *username; + std::map<std::string, std::string> o_account; + + try + { + lua::stack st(L); + // get args + st.at(1, username); + o_account = get_account_object(username); + + st.push(o_account); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + + return 1; + } + + /* Get account attribute value */ + extern int __account_get_attr(lua_State* L) + { + const char *username, *attrkey; + int attrtype; + std::string attrvalue; + std::map<std::string, std::string> o_account; + + try + { + lua::stack st(L); + // get args + st.at(1, username); + st.at(2, attrkey); + st.at(3, attrtype); + + if (t_account *account = accountlist_find_account(username)) + { + switch ((t_attr_type)attrtype) + { + case attr_type_str: + attrvalue = account_get_strattr(account, attrkey); + break; + case attr_type_num: + attrvalue = std::to_string(account_get_numattr(account, attrkey)); + break; + case attr_type_bool: + attrvalue = account_get_boolattr(account, attrkey) == 0 ? "false" : "true"; + break; + case attr_type_raw: + attrvalue = account_get_rawattr(account, attrkey); + break; + } + } + + st.push(attrvalue); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + + return 1; + } + + /* Set account attribute value + * (Return 0 if attribute is not set, and 1 if set) + */ + extern int __account_set_attr(lua_State* L) + { + const char *username, *attrkey; + int attrtype; + std::map<std::string, std::string> o_account; + int result = 0; + + try + { + lua::stack st(L); + // get args + st.at(1, username); + st.at(2, attrkey); + st.at(3, attrtype); + + if (t_account *account = accountlist_find_account(username)) + { + switch ((t_attr_type)attrtype) + { + case attr_type_str: + const char * strvalue; + st.at(4, strvalue); + + if (account_set_strattr(account, attrkey, strvalue) >= 0) + result = 1; + break; + case attr_type_num: + int numvalue; + st.at(4, numvalue); + + if (account_set_numattr(account, attrkey, numvalue) >= 0) + result = 1; + break; + case attr_type_bool: + bool boolvalue; + st.at(4, boolvalue); + + if (account_set_boolattr(account, attrkey, boolvalue ? 1 : 0) >= 0) + result = 1; + break; + case attr_type_raw: + const char * rawvalue; + int length; + st.at(4, rawvalue); + st.at(5, length); + + if (account_set_rawattr(account, attrkey, rawvalue, length) >= 0) + result = 1; + break; + } + } + st.push(result); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + return 1; + } + + + + /* Get friend list of account */ + extern int __account_get_friends(lua_State* L) + { + const char *username; + std::vector<std::map<std::string, std::string>> friends; + + try + { + lua::stack st(L); + // get args + st.at(1, username); + + if (t_account * account = accountlist_find_account(username)) + if (t_list *friendlist = account_get_friends(account)) + { + t_elem const * curr; + t_friend * f; + LIST_TRAVERSE_CONST(friendlist, curr) + { + if (!(f = (t_friend*)elem_get_data(curr))) + { + eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list"); + continue; + } + friends.push_back(get_friend_object(f)); + } + } + st.push(friends); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + return 1; + } + + + /* Get team list of account */ + extern int __account_get_teams(lua_State* L) + { + const char *username; + std::vector<std::map<std::string, std::string>> teams; + + try + { + lua::stack st(L); + // get args + st.at(1, username); + + if (t_account * account = accountlist_find_account(username)) + if (t_list *teamlist = account_get_teams(account)) + { + t_elem const * curr; + t_team * t; + LIST_TRAVERSE_CONST(teamlist, curr) + { + if (!(t = (t_team*)elem_get_data(curr))) + { + eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list"); + continue; + } + teams.push_back(get_team_object(t)); + } + } + st.push(teams); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + return 1; + } + + /* Get clan member list */ + extern int __clan_get_members(lua_State* L) + { + unsigned int clanid; + std::vector<std::map<std::string, std::string>> members; + + try + { + lua::stack st(L); + // get args + st.at(1, clanid); + + if (t_clan * clan = clanlist_find_clan_by_clanid(clanid)) + if (t_list * clanmembers = clan_get_members(clan)) + { + t_elem const * curr; + LIST_TRAVERSE_CONST(clanmembers, curr) + { + t_clanmember * m; + if (!(m = (t_clanmember*)elem_get_data(curr))) + { + eventlog(eventlog_level_error, __FUNCTION__, "got NULL elem in list"); + continue; + } + members.push_back(get_clanmember_object(m)); + } + } + st.push(members); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + return 1; + } + + /* Get one game table object */ + extern int __game_get_by_id(lua_State* L) + { + unsigned int gameid; + std::map<std::string, std::string> o_game; + try + { + lua::stack st(L); + // get args + st.at(1, gameid); + o_game = get_game_object(gameid); + + st.push(o_game); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + + return 1; + } + + /* Get one channel table object */ + extern int __channel_get_by_id(lua_State* L) + { + unsigned int channelid; + std::map<std::string, std::string> o_channel; + try + { + lua::stack st(L); + // get args + st.at(1, channelid); + o_channel = get_channel_object(channelid); + + st.push(o_channel); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + + return 1; + } + + + /* Get usernames online. If allusers = true then return all server users */ + extern int __server_get_users(lua_State* L) + { + bool all = false; + const char *username; + std::map<unsigned int, std::string> users; + t_connection * conn; + t_account * account; + + try + { + lua::stack st(L); + // get args + st.at(1, all); + + if (all) + { + t_entry * curr; + HASHTABLE_TRAVERSE(accountlist(), curr) + { + if (account = (t_account*)entry_get_data(curr)) + users[account_get_uid(account)] = account_get_name(account); + } + } + else + { + t_elem const * curr; + LIST_TRAVERSE_CONST(connlist(), curr) + { + if (conn = (t_connection*)elem_get_data(curr)) + users[conn_get_userid(conn)] = conn_get_username(conn); + } + } + st.push(users); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + return 1; + } + /* Get game list table (id => name) */ + extern int __server_get_games(lua_State* L) + { + std::map<unsigned int, std::string> games; + t_game * game; + + try + { + lua::stack st(L); + + t_elist * curr; + elist_for_each(curr, gamelist()) + { + if (game = elist_entry(curr, t_game, glist_link)) + games[game_get_id(game)] = game_get_name(game); + } + st.push(games); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + return 1; + } + + /* Get channel list (id => name) */ + extern int __server_get_channels(lua_State* L) + { + std::map<unsigned int, std::string> channels; + t_channel * channel; + + try + { + lua::stack st(L); + + t_elem * curr; + LIST_TRAVERSE(channellist(), curr) + { + if (channel = (t_channel*)elem_get_data(curr)) + channels[channel_get_channelid(channel)] = channel_get_name(channel); + } + st.push(channels); + } + catch (const std::exception& e) + { + eventlog(eventlog_level_error, __FUNCTION__, e.what()); + } + catch (...) + { + eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); + } + return 1; + } + + + } +} \ No newline at end of file diff --git a/src/bnetd/luafunctions.h b/src/bnetd/luafunctions.h new file mode 100644 index 0000000..e268492 --- /dev/null +++ b/src/bnetd/luafunctions.h @@ -0,0 +1,52 @@ +/* +* Copyright (C) 2014 HarpyWar (harpywar@gmail.com) +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +/*****/ +#ifndef JUST_NEED_TYPES +#ifndef INCLUDED_LUAFUNCTION_PROTOS +#define INCLUDED_LUAFUNCTION_PROTOS + +#define JUST_NEED_TYPES +#include "luawrapper.h" +#undef JUST_NEED_TYPES + +namespace pvpgn +{ + + namespace bnetd + { + + extern int __message_send_text(lua_State* L); + extern int __eventlog(lua_State* L); + extern int __account_get_by_name(lua_State* L); + extern int __account_get_attr(lua_State* L); + extern int __account_set_attr(lua_State* L); + extern int __account_get_friends(lua_State* L); + extern int __account_get_teams(lua_State* L); + extern int __clan_get_members(lua_State* L); + extern int __game_get_by_id(lua_State* L); + extern int __channel_get_by_id(lua_State* L); + + extern int __server_get_users(lua_State* L); + extern int __server_get_games(lua_State* L); + extern int __server_get_channels(lua_State* L); + } + +} + +#endif +#endif diff --git a/src/bnetd/luainterface.cpp b/src/bnetd/luainterface.cpp index 027cb52..4cdc748 100644 --- a/src/bnetd/luainterface.cpp +++ b/src/bnetd/luainterface.cpp @@ -16,13 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "common/setup_before.h" -#define ACCOUNT_INTERNAL_ACCESS -#define GAME_INTERNAL_ACCESS -#define CHANNEL_INTERNAL_ACCESS -#define CLAN_INTERNAL_ACCESS -#define TEAM_INTERNAL_ACCESS -#include "command.h" #include "team.h" #include <cctype> @@ -31,27 +25,12 @@ #include <cstdlib> - #include "compat/strcasecmp.h" #include "compat/snprintf.h" #include "compat/pdir.h" #include "common/tag.h" #include "common/util.h" -#include "common/version.h" #include "common/eventlog.h" -#include "common/bnettime.h" -#include "common/addr.h" -#include "common/packet.h" -#include "common/bnethash.h" -#include "common/list.h" -#include "common/proginfo.h" -#include "common/queue.h" -#include "common/bn_type.h" -#include "common/xalloc.h" -#include "common/xstr.h" -#include "common/trans.h" -#include "common/lstr.h" -#include "common/hashtable.h" #include "connection.h" #include "message.h" @@ -59,27 +38,18 @@ #include "game.h" #include "account.h" #include "account_wrap.h" -#include "server.h" -#include "prefs.h" -#include "ladder.h" #include "timer.h" -#include "helpfile.h" -#include "mail.h" -#include "runprog.h" -#include "alias_command.h" -#include "realm.h" #include "ipban.h" #include "command_groups.h" -#include "news.h" -#include "topic.h" #include "friends.h" #include "clan.h" -#include "common/flags.h" +#include "prefs.h" -#include "attrlayer.h" #include "luawrapper.h" #include "luainterface.h" +#include "luafunctions.h" +#include "luaobjects.h" #include "common/setup_after.h" @@ -92,49 +62,11 @@ namespace pvpgn { lua::vm vm; - void _register_functions(); - - std::map<std::string, std::string> get_account_object(const char *username); - std::map<std::string, std::string> get_account_object(t_account *account); - std::map<std::string, std::string> get_game_object(unsigned int gameid); - std::map<std::string, std::string> get_game_object(t_game * game); - std::map<std::string, std::string> get_channel_object(unsigned int channelid); - std::map<std::string, std::string> get_channel_object(t_channel * channel); - std::map<std::string, std::string> get_clan_object(t_clan * clan); - std::map<std::string, std::string> get_clanmember_object(t_clanmember * member); - std::map<std::string, std::string> get_team_object(t_team * team); - std::map<std::string, std::string> get_friend_object(t_friend * f); - - - template <class T, class A> - T join(const A &begin, const A &end, const T &t); - - int _sum(lua_State* L); - int __message_send_text(lua_State* L); - int __eventlog(lua_State* L); - int __account_get_by_name(lua_State* L); - int __account_get_attr(lua_State* L); - int __account_set_attr(lua_State* L); - int __account_get_friends(lua_State* L); - int __account_get_teams(lua_State* L); - int __clan_get_members(lua_State* L); - int __game_get_by_id(lua_State* L); - int __channel_get_by_id(lua_State* L); - - int __server_get_users(lua_State* L); - int __server_get_games(lua_State* L); - int __server_get_channels(lua_State* L); - char _msgtemp[MAX_MESSAGE_LEN]; char _msgtemp2[MAX_MESSAGE_LEN]; - typedef enum { - attr_type_str, - attr_type_num, - attr_type_bool, - attr_type_raw - } t_attr_type; + void _register_functions(); /* Unload all the lua scripts */ @@ -182,31 +114,175 @@ namespace pvpgn /* Register C++ functions to be able use them from lua scripts */ void _register_functions() { + // register package 'api' with functions + static const luaL_Reg api[] = + { + { "message_send_text", __message_send_text }, + { "eventlog", __eventlog }, + { "account_get_by_name", __account_get_by_name }, + { "account_get_attr", __account_get_attr }, + { "account_set_attr", __account_set_attr }, + { "account_get_friends", __account_get_friends }, + { "account_get_teams", __account_get_teams }, + { "clan_get_members", __clan_get_members }, + { "game_get_by_id", __game_get_by_id }, + { "channel_get_by_id", __channel_get_by_id }, + + { "server_get_users", __server_get_users }, + { "server_get_games", __server_get_games }, + { "server_get_channels", __server_get_channels }, + { 0, 0 } + }; + vm.reg("api", api); + + // register standalone functions + //vm.reg("sum", _sum); // (test function) + + + // global variables lua::table g(vm); g.update("PVPGN_SOFTWARE", PVPGN_SOFTWARE); g.update("PVPGN_VERSION", PVPGN_VERSION); - // register CFunction - vm.reg("sum", _sum); - vm.reg("message_send_text", __message_send_text); - vm.reg("eventlog", __eventlog); - vm.reg("account_get_by_name", __account_get_by_name); - vm.reg("account_get_attr", __account_get_attr); - vm.reg("account_set_attr", __account_set_attr); - vm.reg("account_get_friends", __account_get_friends); - vm.reg("account_get_teams", __account_get_teams); - vm.reg("clan_get_members", __clan_get_members); - vm.reg("game_get_by_id", __game_get_by_id); - vm.reg("channel_get_by_id", __channel_get_by_id); - - vm.reg("server_get_users", __server_get_users); - vm.reg("server_get_games", __server_get_games); - vm.reg("server_get_channels", __server_get_channels); + // config variables from bnetd.conf + lua::transaction bind(vm); + bind.lookup("config"); + { + lua::table bnetd = bind.table(); + g.update("filedir", prefs_get_filedir()); + g.update("scriptdir", prefs_get_scriptdir()); + g.update("reportdir", prefs_get_reportdir()); + g.update("chanlogdir", prefs_get_chanlogdir()); + g.update("motdfile", prefs_get_motdfile()); + g.update("motdw3file", prefs_get_motdw3file()); + g.update("issuefile", prefs_get_issuefile()); + g.update("channelfile", prefs_get_channelfile()); + g.update("newsfile", prefs_get_newsfile()); + g.update("adfile", prefs_get_adfile()); + g.update("topicfile", prefs_get_topicfile()); + g.update("ipbanfile", prefs_get_ipbanfile()); + g.update("helpfile", prefs_get_helpfile()); + g.update("mpqfile", prefs_get_mpqfile()); + g.update("logfile", prefs_get_logfile()); + g.update("realmfile", prefs_get_realmfile()); + g.update("maildir", prefs_get_maildir()); + g.update("versioncheck_file", prefs_get_versioncheck_file()); + g.update("mapsfile", prefs_get_mapsfile()); + g.update("xplevelfile", prefs_get_xplevel_file()); + g.update("xpcalcfile", prefs_get_xpcalc_file()); + g.update("ladderdir", prefs_get_ladderdir()); + g.update("command_groups_file", prefs_get_command_groups_file()); + g.update("tournament_file", prefs_get_tournament_file()); + g.update("statusdir", prefs_get_outputdir()); + g.update("aliasfile", prefs_get_aliasfile()); + g.update("anongame_infos_file", prefs_get_anongame_infos_file()); + g.update("DBlayoutfile", prefs_get_DBlayoutfile()); + g.update("supportfile", prefs_get_supportfile()); + g.update("transfile", prefs_get_transfile()); + g.update("customicons_file", prefs_get_customicons_file()); + g.update("loglevels", prefs_get_loglevels()); + g.update("d2cs_version", prefs_get_d2cs_version()); + g.update("allow_d2cs_setname", prefs_allow_d2cs_setname()); + g.update("iconfile", prefs_get_iconfile()); + g.update("war3_iconfile", prefs_get_war3_iconfile()); + g.update("star_iconfile", prefs_get_star_iconfile()); + g.update("tosfile", prefs_get_tosfile()); + g.update("allowed_clients", prefs_get_allowed_clients()); + g.update("skip_versioncheck", prefs_get_skip_versioncheck()); + g.update("allow_bad_version", prefs_get_allow_bad_version()); + g.update("allow_unknown_version", prefs_get_allow_unknown_version()); + g.update("version_exeinfo_match", prefs_get_version_exeinfo_match()); + g.update("version_exeinfo_maxdiff", prefs_get_version_exeinfo_maxdiff()); + g.update("usersync", prefs_get_user_sync_timer()); + g.update("userflush", prefs_get_user_flush_timer()); + g.update("userstep", prefs_get_user_step()); + g.update("latency", prefs_get_latency()); + g.update("nullmsg", prefs_get_nullmsg()); + g.update("shutdown_delay", prefs_get_shutdown_delay()); + g.update("shutdown_decr", prefs_get_shutdown_decr()); + g.update("ipban_check_int", prefs_get_ipban_check_int()); + g.update("new_accounts", prefs_get_allow_new_accounts()); + g.update("max_accounts", prefs_get_max_accounts()); + g.update("kick_old_login", prefs_get_kick_old_login()); + g.update("ask_new_channel", prefs_get_ask_new_channel()); + g.update("report_all_games", prefs_get_report_all_games()); + g.update("report_diablo_games", prefs_get_report_diablo_games()); + g.update("hide_pass_games", prefs_get_hide_pass_games()); + g.update("hide_started_games", prefs_get_hide_started_games()); + g.update("hide_temp_channels", prefs_get_hide_temp_channels()); + g.update("extra_commands", prefs_get_extra_commands()); + g.update("disc_is_loss", prefs_get_discisloss()); + g.update("ladder_games", prefs_get_ladder_games()); + g.update("ladder_prefix", prefs_get_ladder_prefix()); + g.update("enable_conn_all", prefs_get_enable_conn_all()); + g.update("hide_addr", prefs_get_hide_addr()); + g.update("chanlog", prefs_get_chanlog()); + g.update("quota", prefs_get_quota()); + g.update("quota_lines", prefs_get_quota_lines()); + g.update("quota_time", prefs_get_quota_time()); + g.update("quota_wrapline", prefs_get_quota_wrapline()); + g.update("quota_maxline", prefs_get_quota_maxline()); + g.update("quota_dobae", prefs_get_quota_dobae()); + g.update("mail_support", prefs_get_mail_support()); + g.update("mail_quota", prefs_get_mail_quota()); + g.update("log_notice", prefs_get_log_notice()); + g.update("passfail_count", prefs_get_passfail_count()); + g.update("passfail_bantime", prefs_get_passfail_bantime()); + g.update("maxusers_per_channel", prefs_get_maxusers_per_channel()); + g.update("savebyname", prefs_get_savebyname()); + g.update("sync_on_logoff", prefs_get_sync_on_logoff()); + g.update("hashtable_size", prefs_get_hashtable_size()); + g.update("account_allowed_symbols", prefs_get_account_allowed_symbols()); + g.update("account_force_username", prefs_get_account_force_username()); + g.update("max_friends", prefs_get_max_friends()); + g.update("track", prefs_get_track()); + g.update("trackaddrs", prefs_get_trackserv_addrs()); + g.update("location", prefs_get_location()); + g.update("description", prefs_get_description()); + g.update("url", prefs_get_url()); + g.update("contact_name", prefs_get_contact_name()); + g.update("contact_email", prefs_get_contact_email()); + g.update("servername", prefs_get_servername()); + g.update("max_connections", prefs_get_max_connections()); + g.update("max_concurrent_logins", prefs_get_max_concurrent_logins()); + g.update("use_keepalive", prefs_get_use_keepalive()); + g.update("max_conns_per_IP", prefs_get_max_conns_per_IP()); + g.update("servaddrs", prefs_get_bnetdserv_addrs()); + g.update("udptest_port", prefs_get_udptest_port()); + g.update("w3routeaddr", prefs_get_w3route_addr()); + g.update("initkill_timer", prefs_get_initkill_timer()); + g.update("wolv1addrs", prefs_get_wolv1_addrs()); + g.update("wolv2addrs", prefs_get_wolv2_addrs()); + g.update("wgameresaddrs", prefs_get_wgameres_addrs()); + g.update("apiregaddrs", prefs_get_apireg_addrs()); + g.update("woltimezone", prefs_get_wol_timezone()); + g.update("wollongitude", prefs_get_wol_longitude()); + g.update("wollatitude", prefs_get_wol_latitude()); + g.update("wol_autoupdate_serverhost", prefs_get_wol_autoupdate_serverhost()); + g.update("wol_autoupdate_username", prefs_get_wol_autoupdate_username()); + g.update("wol_autoupdate_password", prefs_get_wol_autoupdate_password()); + g.update("ircaddrs", prefs_get_irc_addrs()); + g.update("irc_network_name", prefs_get_irc_network_name()); + g.update("hostname", prefs_get_hostname()); + g.update("irc_latency", prefs_get_irc_latency()); + g.update("telnetaddrs", prefs_get_telnet_addrs()); + g.update("war3_ladder_update_secs", prefs_get_war3_ladder_update_secs()); + g.update("XML_output_ladder", prefs_get_XML_output_ladder()); + g.update("output_update_secs", prefs_get_output_update_secs()); + g.update("XML_status_output", prefs_get_XML_status_output()); + g.update("clan_newer_time", prefs_get_clan_newer_time()); + g.update("clan_max_members", prefs_get_clan_max_members()); + g.update("clan_channel_default_private", prefs_get_clan_channel_default_private()); + g.update("clan_min_invites", prefs_get_clan_min_invites()); + } } + + + /* Lua Events (called from scripts) */ #ifndef _LUA_EVENTS_ @@ -393,813 +469,6 @@ namespace pvpgn #endif - /* --- Lua Functions (called from scripts) */ -#ifndef _LUA_FUNCTIONS_ - /* Send message text to user */ - int __message_send_text(lua_State* L) - { - const char *text; - const char *username_src, *username_dst; - int message_type; - t_connection *c_src = NULL, *c_dst = NULL; - - try - { - lua::stack st(L); - // get args - st.at(1, username_dst); - st.at(2, message_type); - st.at(3, username_src); - st.at(4, text); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - - // get user connections - if (t_account * account = accountlist_find_account(username_dst)) - c_dst = account_get_conn(account); - - if (username_src) - if (t_account * account = accountlist_find_account(username_src)) - c_src = account_get_conn(account); - - // send message - // (source can be NULL, but destination cant) - if (c_dst) - message_send_text(c_dst, (t_message_type)message_type, c_src, text); - - return 0; - } - - /* Log text into logfile */ - int __eventlog(lua_State* L) - { - int loglevel; - const char *text, *function; - - try - { - lua::stack st(L); - // get args - st.at(1, loglevel); - st.at(2, function); - st.at(3, text); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - eventlog(t_eventlog_level(loglevel), function, text); - - return 0; - } - - /* Get one account table object */ - int __account_get_by_name(lua_State* L) - { - const char *username; - std::map<std::string, std::string> o_account; - - try - { - lua::stack st(L); - // get args - st.at(1, username); - o_account = get_account_object(username); - - st.push(o_account); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - - return 1; - } - - /* Get account attribute value */ - int __account_get_attr(lua_State* L) - { - const char *username, *attrkey; - int attrtype; - std::string attrvalue; - std::map<std::string, std::string> o_account; - - try - { - lua::stack st(L); - // get args - st.at(1, username); - st.at(2, attrkey); - st.at(3, attrtype); - - if (t_account *account = accountlist_find_account(username)) - { - switch ((t_attr_type)attrtype) - { - case attr_type_str: - attrvalue = account_get_strattr(account, attrkey); - break; - case attr_type_num: - attrvalue = std::to_string(account_get_numattr(account, attrkey)); - break; - case attr_type_bool: - attrvalue = account_get_boolattr(account, attrkey) == 0 ? "false" : "true"; - break; - case attr_type_raw: - attrvalue = account_get_rawattr(account, attrkey); - break; - } - } - - st.push(attrvalue); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - - return 1; - } - - /* Set account attribute value - * (Return 0 if attribute is not set, and 1 if set) - */ - int __account_set_attr(lua_State* L) - { - const char *username, *attrkey; - int attrtype; - std::map<std::string, std::string> o_account; - int result = 0; - - try - { - lua::stack st(L); - // get args - st.at(1, username); - st.at(2, attrkey); - st.at(3, attrtype); - - if (t_account *account = accountlist_find_account(username)) - { - switch ((t_attr_type)attrtype) - { - case attr_type_str: - const char * strvalue; - st.at(4, strvalue); - - if (account_set_strattr(account, attrkey, strvalue) >= 0) - result = 1; - break; - case attr_type_num: - int numvalue; - st.at(4, numvalue); - - if (account_set_numattr(account, attrkey, numvalue) >= 0) - result = 1; - break; - case attr_type_bool: - bool boolvalue; - st.at(4, boolvalue); - - if (account_set_boolattr(account, attrkey, boolvalue ? 1 : 0) >= 0) - result = 1; - break; - case attr_type_raw: - const char * rawvalue; - int length; - st.at(4, rawvalue); - st.at(5, length); - - if (account_set_rawattr(account, attrkey, rawvalue, length) >= 0) - result = 1; - break; - } - } - st.push(result); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - return 1; - } - - - - /* Get friend list of account */ - int __account_get_friends(lua_State* L) - { - const char *username; - std::vector<std::map<std::string, std::string>> friends; - - try - { - lua::stack st(L); - // get args - st.at(1, username); - - if (t_account * account = accountlist_find_account(username)) - if (account->friends) - { - t_elem const * curr; - t_friend * f; - LIST_TRAVERSE_CONST(account->friends, curr) - { - if (!(f = (t_friend*)elem_get_data(curr))) - { - eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list"); - continue; - } - friends.push_back(get_friend_object(f)); - } - } - st.push(friends); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - return 1; - } - - - /* Get team list of account */ - int __account_get_teams(lua_State* L) - { - const char *username; - std::vector<std::map<std::string, std::string>> teams; - - try - { - lua::stack st(L); - // get args - st.at(1, username); - - if (t_account * account = accountlist_find_account(username)) - if (account->teams) - { - t_elem const * curr; - t_team * t; - LIST_TRAVERSE_CONST(account->teams, curr) - { - if (!(t = (t_team*)elem_get_data(curr))) - { - eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list"); - continue; - } - teams.push_back(get_team_object(t)); - } - } - st.push(teams); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - return 1; - } - - /* Get clan member list */ - int __clan_get_members(lua_State* L) - { - unsigned int clanid; - std::vector<std::map<std::string, std::string>> members; - - try - { - lua::stack st(L); - // get args - st.at(1, clanid); - - if (t_clan * clan = clanlist_find_clan_by_clanid(clanid)) - if (clan->members) - { - t_elem const * curr; - LIST_TRAVERSE_CONST(clan->members, curr) - { - t_clanmember * m; - if (!(m = (t_clanmember*)elem_get_data(curr))) - { - eventlog(eventlog_level_error, __FUNCTION__, "got NULL elem in list"); - continue; - } - members.push_back(get_clanmember_object(m)); - } - } - st.push(members); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - return 1; - } - - /* Get one game table object */ - int __game_get_by_id(lua_State* L) - { - unsigned int gameid; - std::map<std::string, std::string> o_game; - try - { - lua::stack st(L); - // get args - st.at(1, gameid); - o_game = get_game_object(gameid); - - st.push(o_game); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - - return 1; - } - - /* Get one channel table object */ - int __channel_get_by_id(lua_State* L) - { - unsigned int channelid; - std::map<std::string, std::string> o_channel; - try - { - lua::stack st(L); - // get args - st.at(1, channelid); - o_channel = get_channel_object(channelid); - - st.push(o_channel); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - - return 1; - } - - - /* Get usernames online. If allusers = true then return all server users */ - int __server_get_users(lua_State* L) - { - bool all = false; - const char *username; - std::map<unsigned int, std::string> users; - t_connection * conn; - t_account * account; - - try - { - lua::stack st(L); - // get args - st.at(1, all); - - if (all) - { - t_entry * curr; - HASHTABLE_TRAVERSE(accountlist(), curr) - { - if (account = (t_account*)entry_get_data(curr)) - users[account_get_uid(account)] = account_get_name(account); - } - } - else - { - t_elem const * curr; - LIST_TRAVERSE_CONST(connlist(), curr) - { - if (conn = (t_connection*)elem_get_data(curr)) - users[conn_get_userid(conn)] = conn_get_username(conn); - } - } - st.push(users); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - return 1; - } - /* Get game list table (id => name) */ - int __server_get_games(lua_State* L) - { - std::map<unsigned int, std::string> games; - t_game * game; - - try - { - lua::stack st(L); - - t_elist * curr; - elist_for_each(curr, gamelist()) - { - if (game = elist_entry(curr, t_game, glist_link)) - games[game_get_id(game)] = game_get_name(game); - } - st.push(games); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - return 1; - } - - /* Get channel list (id => name) */ - int __server_get_channels(lua_State* L) - { - std::map<unsigned int, std::string> channels; - t_channel * channel; - - try - { - lua::stack st(L); - - t_elem * curr; - LIST_TRAVERSE(channellist(), curr) - { - if (channel = (t_channel*)elem_get_data(curr)) - channels[channel_get_channelid(channel)] = channel_get_name(channel); - } - st.push(channels); - } - catch (const std::exception& e) - { - eventlog(eventlog_level_error, __FUNCTION__, e.what()); - } - catch (...) - { - eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); - } - return 1; - } - - - - // TODO: remove it - /* Just a test function */ - int _sum(lua_State* L) - { - lua::stack st(L); - - double a = 0, b = 0; - - st.at(1, a); // begin from 1 - st.at(2, b); - - st.push(a + b); - - return 1; // number of return values (st.push) - } - -#endif - - std::map<std::string, std::string> get_account_object(const char * username) - { - std::map<std::string, std::string> o_account; - - if (t_account * account = accountlist_find_account(username)) - o_account = get_account_object(account); - return o_account; - } - std::map<std::string, std::string> get_account_object(t_account * account) - { - std::map<std::string, std::string> o_account; - - if (!account) - return o_account; - - o_account["id"] = std::to_string(account_get_uid(account)); - o_account["name"] = account_get_name(account); - o_account["email"] = account_get_email(account); - o_account["commandgroups"] = std::to_string(account_get_command_groups(account)); - o_account["locked"] = account_get_auth_lock(account) ? "true" : "false"; - o_account["muted"] = account_get_auth_mute(account) ? "true" : "false"; - - // if user online - if (t_connection * c = account_get_conn(account)) - { - o_account["country"] = conn_get_country(c); - o_account["clientver"] = conn_get_clientver(c); - o_account["latency"] = std::to_string(conn_get_latency(c)); - if (t_clienttag clienttag = conn_get_clienttag(c)) - o_account["clienttag"] = clienttag_uint_to_str(clienttag); - if (t_game *game = conn_get_game(c)) - o_account["game_id"] = std::to_string(game_get_id(game)); - if (t_channel *channel = conn_get_channel(c)) - o_account["channel_id"] = std::to_string(channel_get_channelid(channel)); - } - - if (account->clanmember) - o_account["clan_id"] = account->clanmember->clan->clanid; - - // - friends can be get from lua_account_get_friends - // - teams can be get from lua_account_get_teams - - return o_account; - } - - std::map<std::string, std::string> get_game_object(unsigned int gameid) - { - std::map<std::string, std::string> o_game; - - if (t_game * game = gamelist_find_game_byid(gameid)) - o_game = get_game_object(game); - return o_game; - } - std::map<std::string, std::string> get_game_object(t_game * game) - { - std::map<std::string, std::string> o_game; - - if (!game) - return o_game; - - o_game["id"] = std::to_string(game->id); - o_game["name"] = game->name; - o_game["pass"] = game->pass; - o_game["info"] = game->info; - o_game["type"] = std::to_string(game->type); - o_game["flag"] = std::to_string(game->flag); - - o_game["address"] = addr_num_to_ip_str(game->addr); - o_game["port"] = std::to_string(game->port); - o_game["status"] = std::to_string(game->status); - o_game["currentplayers"] = std::to_string(game->ref); - o_game["totalplayers"] = std::to_string(game->count); - o_game["maxplayers"] = std::to_string(game->maxplayers); - o_game["mapname"] = game->mapname; - o_game["option"] = std::to_string(game->option); - o_game["maptype"] = std::to_string(game->maptype); - o_game["tileset"] = std::to_string(game->tileset); - o_game["speed"] = std::to_string(game->speed); - o_game["mapsize_x"] = std::to_string(game->mapsize_x); - o_game["mapsize_y"] = std::to_string(game->mapsize_y); - if (t_connection *c = game->owner) - { - if (t_account *account = conn_get_account(c)) - o_game["owner"] = account_get_name(account); - } - - std::vector<std::string> players; - for (int i = 0; i < game->ref; i++) - { - if (t_account *account = game->players[i]) - players.push_back(account_get_name(account)); - } - o_game["players"] = join(players.begin(), players.end(), std::string(",")); - - - o_game["bad"] = std::to_string(game->bad); // if 1, then the results will be ignored - - std::vector<std::string> results; - if (game->results) - { - for (int i = 0; i < game->count; i++) - results.push_back(std::to_string(game->results[i])); - } - o_game["results"] = join(results.begin(), results.end(), std::string(",")); - // UNDONE: add report_heads and report_bodies: they are XML strings - - o_game["create_time"] = std::to_string(game->create_time); - o_game["start_time"] = std::to_string(game->start_time); - o_game["lastaccess_time"] = std::to_string(game->lastaccess_time); - - o_game["difficulty"] = std::to_string(game->difficulty); - o_game["version"] = vernum_to_verstr(game->version); - o_game["startver"] = std::to_string(game->startver); - - if (t_clienttag clienttag = game->clienttag) - o_game["clienttag"] = clienttag_uint_to_str(clienttag); - - - if (game->description) - o_game["description"] = game->description; - if (game->realmname) - o_game["realmname"] = game->realmname; - - return o_game; - } - - std::map<std::string, std::string> get_channel_object(unsigned int channelid) - { - std::map<std::string, std::string> o_channel; - - if (t_channel * channel = channellist_find_channel_bychannelid(channelid)) - o_channel = get_channel_object(channel); - return o_channel; - } - std::map<std::string, std::string> get_channel_object(t_channel * channel) - { - std::map<std::string, std::string> o_channel; - - if (!channel) - return o_channel; - - o_channel["id"] = std::to_string(channel->id); - o_channel["name"] = channel->name; - if (channel->shortname) - o_channel["shortname"] = channel->shortname; - if (channel->country) - o_channel["country"] = channel->country; - o_channel["flags"] = std::to_string(channel->flags); - o_channel["maxmembers"] = std::to_string(channel->maxmembers); - o_channel["currmembers"] = std::to_string(channel->currmembers); - - o_channel["clienttag"] = clienttag_uint_to_str(channel->clienttag); - if (channel->realmname) - o_channel["realmname"] = channel->realmname; - if (channel->logname) - o_channel["logname"] = channel->logname; - - - // Westwood Online Extensions - o_channel["minmembers"] = std::to_string(channel->minmembers); - o_channel["gameType"] = std::to_string(channel->gameType); - if (channel->gameExtension) - o_channel["gameExtension"] = channel->gameExtension; - - - std::vector<std::string> members; - if (channel->memberlist) - { - t_channelmember *m = channel->memberlist; - while (m) - { - if (t_account *account = conn_get_account(m->connection)) - members.push_back(account_get_name(account)); - m = m->next; - } - } - o_channel["memberlist"] = join(members.begin(), members.end(), std::string(",")); - - std::vector<std::string> bans; - if (channel->banlist) - { - t_elem const * curr; - LIST_TRAVERSE_CONST(channel->banlist, curr) - { - char * b; - if (!(b = (char*)elem_get_data(curr))) - { - eventlog(eventlog_level_error, __FUNCTION__, "found NULL name in banlist"); - continue; - } - members.push_back(b); - } - } - o_channel["banlist"] = join(bans.begin(), bans.end(), std::string(",")); - - return o_channel; - } - - - std::map<std::string, std::string> get_clan_object(t_clan * clan) - { - std::map<std::string, std::string> o_clan; - - if (!clan) - return o_clan; - - o_clan["id"] = std::to_string(clan->clanid); - o_clan["tag"] = clantag_to_str(clan->tag); - o_clan["clanname"] = clan->clanname; - o_clan["created"] = std::to_string(clan->created); - o_clan["creation_time"] = std::to_string(clan->creation_time); - o_clan["clan_motd"] = clan->clan_motd; - o_clan["channel_type"] = std::to_string(clan->channel_type); // 0--public 1--private - - // - clanmembers can be get from lua_clan_get_members - - return o_clan; - } - - std::map<std::string, std::string> get_clanmember_object(t_clanmember * member) - { - std::map<std::string, std::string> o_member; - - if (!member) - return o_member; - - o_member["username"] = account_get_name(member->memberacc); - o_member["status"] = member->status; - o_member["clan_id"] = std::to_string(member->clan->clanid); - o_member["join_time"] = std::to_string(member->join_time); - o_member["fullmember"] = std::to_string(member->fullmember);// 0 -- clanmember is only invited, 1 -- clanmember is fullmember - - return o_member; - } - - std::map<std::string, std::string> get_team_object(t_team * team) - { - std::map<std::string, std::string> o_team; - - if (!team) - return o_team; - - o_team["id"] = std::to_string(team->teamid); - o_team["size"] = std::to_string(team->size); - - o_team["clienttag"] = clienttag_uint_to_str(team->clienttag); - o_team["lastgame"] = std::to_string(team->lastgame); - o_team["wins"] = std::to_string(team->wins); - o_team["losses"] = std::to_string(team->losses); - o_team["xp"] = std::to_string(team->xp); - o_team["level"] = std::to_string(team->level); - o_team["rank"] = std::to_string(team->rank); - - // usernames - std::vector<std::string> members; - if (team->members) - { - for (int i = 0; i < MAX_TEAMSIZE; i++) - members.push_back(account_get_name(team->members[i])); - } - o_team["members"] = join(members.begin(), members.end(), std::string(",")); - - return o_team; - } - - std::map<std::string, std::string> get_friend_object(t_friend * f) - { - std::map<std::string, std::string> o_friend; - - if (!f) - return o_friend; - - o_friend["username"] = account_get_name(f->friendacc); - o_friend["mutual"] = std::to_string(f->mutual); // -1 - unloaded(used to remove deleted elems when reload); 0 - not mutual ; 1 - is mutual - - return o_friend; - } - - - /* Join two vector objects to string by delimeter */ - template <class T, class A> - T join(const A &begin, const A &end, const T &t) - { - T result; - for (A it = begin; - it != end; - it++) - { - if (!result.empty()) - result.append(t); - result.append(*it); - } - return result; - } } } \ No newline at end of file diff --git a/src/bnetd/luainterface.h b/src/bnetd/luainterface.h index 003d84d..4e0feae 100644 --- a/src/bnetd/luainterface.h +++ b/src/bnetd/luainterface.h @@ -17,21 +17,17 @@ */ /*****/ #ifndef JUST_NEED_TYPES -#ifndef INCLUDED_LUA_PROTOS -#define INCLUDED_LUA_PROTOS - - -// FIXME: include one time on pvpgn load -#include "luawrapper.h" -#include <stdio.h> +#ifndef INCLUDED_LUAINTERFACE_PROTOS +#define INCLUDED_LUAINTERFACE_PROTOS #ifdef WIN32 #pragma comment(lib, "lua5.1.lib") #endif - #define JUST_NEED_TYPES #include "connection.h" +#include "luawrapper.h" +#include <stdio.h> #undef JUST_NEED_TYPES namespace pvpgn diff --git a/src/bnetd/luaobjects.cpp b/src/bnetd/luaobjects.cpp new file mode 100644 index 0000000..121291d --- /dev/null +++ b/src/bnetd/luaobjects.cpp @@ -0,0 +1,363 @@ +/* +* Copyright (C) 2014 HarpyWar (harpywar@gmail.com) +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "common/setup_before.h" +#define ACCOUNT_INTERNAL_ACCESS +#define GAME_INTERNAL_ACCESS +#define CHANNEL_INTERNAL_ACCESS +#define CLAN_INTERNAL_ACCESS +#define TEAM_INTERNAL_ACCESS + +#include "team.h" + +#include <cctype> +#include <cerrno> +#include <cstring> +#include <cstdlib> + +#include "compat/strcasecmp.h" +#include "compat/snprintf.h" +#include "common/tag.h" +#include "common/util.h" +#include "common/eventlog.h" +#include "common/list.h" +#include "common/flags.h" +#include "common/proginfo.h" +#include "common/addr.h" + +#include "connection.h" +#include "message.h" +#include "channel.h" +#include "game.h" +#include "account.h" +#include "account_wrap.h" +#include "timer.h" +#include "ipban.h" +#include "command_groups.h" +#include "friends.h" +#include "clan.h" + +#include "luaobjects.h" + +#include "common/setup_after.h" + + +namespace pvpgn +{ + + namespace bnetd + { + template <class T, class A> + T join(const A &begin, const A &end, const T &t); + + + extern std::map<std::string, std::string> get_account_object(const char * username) + { + std::map<std::string, std::string> o_account; + + if (t_account * account = accountlist_find_account(username)) + o_account = get_account_object(account); + return o_account; + } + extern std::map<std::string, std::string> get_account_object(t_account * account) + { + std::map<std::string, std::string> o_account; + + if (!account) + return o_account; + + o_account["id"] = std::to_string(account_get_uid(account)); + o_account["name"] = account_get_name(account); + o_account["email"] = account_get_email(account); + o_account["commandgroups"] = std::to_string(account_get_command_groups(account)); + o_account["locked"] = account_get_auth_lock(account) ? "true" : "false"; + o_account["muted"] = account_get_auth_mute(account) ? "true" : "false"; + + // if user online + if (t_connection * c = account_get_conn(account)) + { + o_account["country"] = conn_get_country(c); + o_account["clientver"] = conn_get_clientver(c); + o_account["latency"] = std::to_string(conn_get_latency(c)); + if (t_clienttag clienttag = conn_get_clienttag(c)) + o_account["clienttag"] = clienttag_uint_to_str(clienttag); + if (t_game *game = conn_get_game(c)) + o_account["game_id"] = std::to_string(game_get_id(game)); + if (t_channel *channel = conn_get_channel(c)) + o_account["channel_id"] = std::to_string(channel_get_channelid(channel)); + } + + if (account->clanmember) + o_account["clan_id"] = account->clanmember->clan->clanid; + + // - friends can be get from lua_account_get_friends + // - teams can be get from lua_account_get_teams + + return o_account; + } + + extern std::map<std::string, std::string> get_game_object(unsigned int gameid) + { + std::map<std::string, std::string> o_game; + + if (t_game * game = gamelist_find_game_byid(gameid)) + o_game = get_game_object(game); + return o_game; + } + extern std::map<std::string, std::string> get_game_object(t_game * game) + { + std::map<std::string, std::string> o_game; + + if (!game) + return o_game; + + o_game["id"] = std::to_string(game->id); + o_game["name"] = game->name; + o_game["pass"] = game->pass; + o_game["info"] = game->info; + o_game["type"] = std::to_string(game->type); + o_game["flag"] = std::to_string(game->flag); + + o_game["address"] = addr_num_to_ip_str(game->addr); + o_game["port"] = std::to_string(game->port); + o_game["status"] = std::to_string(game->status); + o_game["currentplayers"] = std::to_string(game->ref); + o_game["totalplayers"] = std::to_string(game->count); + o_game["maxplayers"] = std::to_string(game->maxplayers); + o_game["mapname"] = game->mapname; + o_game["option"] = std::to_string(game->option); + o_game["maptype"] = std::to_string(game->maptype); + o_game["tileset"] = std::to_string(game->tileset); + o_game["speed"] = std::to_string(game->speed); + o_game["mapsize_x"] = std::to_string(game->mapsize_x); + o_game["mapsize_y"] = std::to_string(game->mapsize_y); + if (t_connection *c = game->owner) + { + if (t_account *account = conn_get_account(c)) + o_game["owner"] = account_get_name(account); + } + + std::vector<std::string> players; + for (int i = 0; i < game->ref; i++) + { + if (t_account *account = game->players[i]) + players.push_back(account_get_name(account)); + } + o_game["players"] = join(players.begin(), players.end(), std::string(",")); + + + o_game["bad"] = std::to_string(game->bad); // if 1, then the results will be ignored + + std::vector<std::string> results; + if (game->results) + { + for (int i = 0; i < game->count; i++) + results.push_back(std::to_string(game->results[i])); + } + o_game["results"] = join(results.begin(), results.end(), std::string(",")); + // UNDONE: add report_heads and report_bodies: they are XML strings + + o_game["create_time"] = std::to_string(game->create_time); + o_game["start_time"] = std::to_string(game->start_time); + o_game["lastaccess_time"] = std::to_string(game->lastaccess_time); + + o_game["difficulty"] = std::to_string(game->difficulty); + o_game["version"] = vernum_to_verstr(game->version); + o_game["startver"] = std::to_string(game->startver); + + if (t_clienttag clienttag = game->clienttag) + o_game["clienttag"] = clienttag_uint_to_str(clienttag); + + + if (game->description) + o_game["description"] = game->description; + if (game->realmname) + o_game["realmname"] = game->realmname; + + return o_game; + } + + extern std::map<std::string, std::string> get_channel_object(unsigned int channelid) + { + std::map<std::string, std::string> o_channel; + + if (t_channel * channel = channellist_find_channel_bychannelid(channelid)) + o_channel = get_channel_object(channel); + return o_channel; + } + extern std::map<std::string, std::string> get_channel_object(t_channel * channel) + { + std::map<std::string, std::string> o_channel; + + if (!channel) + return o_channel; + + o_channel["id"] = std::to_string(channel->id); + o_channel["name"] = channel->name; + if (channel->shortname) + o_channel["shortname"] = channel->shortname; + if (channel->country) + o_channel["country"] = channel->country; + o_channel["flags"] = std::to_string(channel->flags); + o_channel["maxmembers"] = std::to_string(channel->maxmembers); + o_channel["currmembers"] = std::to_string(channel->currmembers); + + o_channel["clienttag"] = clienttag_uint_to_str(channel->clienttag); + if (channel->realmname) + o_channel["realmname"] = channel->realmname; + if (channel->logname) + o_channel["logname"] = channel->logname; + + + // Westwood Online Extensions + o_channel["minmembers"] = std::to_string(channel->minmembers); + o_channel["gameType"] = std::to_string(channel->gameType); + if (channel->gameExtension) + o_channel["gameExtension"] = channel->gameExtension; + + + std::vector<std::string> members; + if (channel->memberlist) + { + t_channelmember *m = channel->memberlist; + while (m) + { + if (t_account *account = conn_get_account(m->connection)) + members.push_back(account_get_name(account)); + m = m->next; + } + } + o_channel["memberlist"] = join(members.begin(), members.end(), std::string(",")); + + std::vector<std::string> bans; + if (channel->banlist) + { + t_elem const * curr; + LIST_TRAVERSE_CONST(channel->banlist, curr) + { + char * b; + if (!(b = (char*)elem_get_data(curr))) + { + eventlog(eventlog_level_error, __FUNCTION__, "found NULL name in banlist"); + continue; + } + members.push_back(b); + } + } + o_channel["banlist"] = join(bans.begin(), bans.end(), std::string(",")); + + return o_channel; + } + + + extern std::map<std::string, std::string> get_clan_object(t_clan * clan) + { + std::map<std::string, std::string> o_clan; + + if (!clan) + return o_clan; + + o_clan["id"] = std::to_string(clan->clanid); + o_clan["tag"] = clantag_to_str(clan->tag); + o_clan["clanname"] = clan->clanname; + o_clan["created"] = std::to_string(clan->created); + o_clan["creation_time"] = std::to_string(clan->creation_time); + o_clan["clan_motd"] = clan->clan_motd; + o_clan["channel_type"] = std::to_string(clan->channel_type); // 0--public 1--private + + // - clanmembers can be get from lua_clan_get_members + + return o_clan; + } + + extern std::map<std::string, std::string> get_clanmember_object(t_clanmember * member) + { + std::map<std::string, std::string> o_member; + + if (!member) + return o_member; + + o_member["username"] = account_get_name(member->memberacc); + o_member["status"] = member->status; + o_member["clan_id"] = std::to_string(member->clan->clanid); + o_member["join_time"] = std::to_string(member->join_time); + o_member["fullmember"] = std::to_string(member->fullmember);// 0 -- clanmember is only invited, 1 -- clanmember is fullmember + + return o_member; + } + + extern std::map<std::string, std::string> get_team_object(t_team * team) + { + std::map<std::string, std::string> o_team; + + if (!team) + return o_team; + + o_team["id"] = std::to_string(team->teamid); + o_team["size"] = std::to_string(team->size); + + o_team["clienttag"] = clienttag_uint_to_str(team->clienttag); + o_team["lastgame"] = std::to_string(team->lastgame); + o_team["wins"] = std::to_string(team->wins); + o_team["losses"] = std::to_string(team->losses); + o_team["xp"] = std::to_string(team->xp); + o_team["level"] = std::to_string(team->level); + o_team["rank"] = std::to_string(team->rank); + + // usernames + std::vector<std::string> members; + if (team->members) + { + for (int i = 0; i < MAX_TEAMSIZE; i++) + members.push_back(account_get_name(team->members[i])); + } + o_team["members"] = join(members.begin(), members.end(), std::string(",")); + + return o_team; + } + + extern std::map<std::string, std::string> get_friend_object(t_friend * f) + { + std::map<std::string, std::string> o_friend; + + if (!f) + return o_friend; + + o_friend["username"] = account_get_name(f->friendacc); + o_friend["mutual"] = std::to_string(f->mutual); // -1 - unloaded(used to remove deleted elems when reload); 0 - not mutual ; 1 - is mutual + + return o_friend; + } + + + /* Join two vector objects to string by delimeter */ + template <class T, class A> + T join(const A &begin, const A &end, const T &t) + { + T result; + for (A it = begin; + it != end; + it++) + { + if (!result.empty()) + result.append(t); + result.append(*it); + } + return result; + } + } +} \ No newline at end of file diff --git a/src/bnetd/luaobjects.h b/src/bnetd/luaobjects.h new file mode 100644 index 0000000..c9460e8 --- /dev/null +++ b/src/bnetd/luaobjects.h @@ -0,0 +1,54 @@ +/* +* Copyright (C) 2014 HarpyWar (harpywar@gmail.com) +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +/*****/ +#ifndef JUST_NEED_TYPES +#ifndef INCLUDED_LUAOBJECTS_PROTOS +#define INCLUDED_LUAOBJECTS_PROTOS + + + +#define JUST_NEED_TYPES +#include "connection.h" +#include <cctype> +#include <cerrno> +#include <cstring> +#include <cstdlib> +#undef JUST_NEED_TYPES + +namespace pvpgn +{ + + namespace bnetd + { + + extern std::map<std::string, std::string> get_account_object(const char *username); + extern std::map<std::string, std::string> get_account_object(t_account *account); + extern std::map<std::string, std::string> get_game_object(unsigned int gameid); + extern std::map<std::string, std::string> get_game_object(t_game * game); + extern std::map<std::string, std::string> get_channel_object(unsigned int channelid); + extern std::map<std::string, std::string> get_channel_object(t_channel * channel); + extern std::map<std::string, std::string> get_clan_object(t_clan * clan); + extern std::map<std::string, std::string> get_clanmember_object(t_clanmember * member); + extern std::map<std::string, std::string> get_team_object(t_team * team); + extern std::map<std::string, std::string> get_friend_object(t_friend * f); + } + +} + +#endif +#endif