New Lua events:

- handle_channel_message
- handle_channel_userjoin
- handle_channel_userleft
- handle_user_whisper
- handle_user_login
- handle_user_disconnect

New Lua functions:
- account_get_friends
- account_get_teams
- clan_get_members
This commit is contained in:
HarpyWar 2014-05-02 22:23:13 +04:00
parent a792b15666
commit 5287c5c266
8 changed files with 446 additions and 50 deletions

View file

@ -42,6 +42,8 @@
#include "irc.h"
#include "common/setup_after.h"
#include "luainterface.h"
namespace pvpgn
{
@ -488,11 +490,15 @@ namespace pvpgn
if (channel->log)
message_send_text(connection, message_type_info, connection, prefs_get_log_notice());
#ifdef WITH_LUA
lua_handle_channel(channel, connection, NULL, message_type_null, luaevent_channel_userjoin);
#endif
return 0;
}
extern int channel_del_connection(t_channel * channel, t_connection * connection, t_message_type mess, char const * text)
extern int channel_del_connection(t_channel * channel, t_connection * connection, t_message_type type, char const * text)
{
t_channelmember * curr;
t_channelmember * temp;
@ -509,7 +515,7 @@ namespace pvpgn
return -1;
}
channel_message_send(channel, mess, connection, text);
channel_message_send(channel, type, connection, text);
channel_message_log(channel, connection, 0, "PARTED");
curr = channel->memberlist;
@ -548,6 +554,10 @@ namespace pvpgn
channel_destroy(channel, &curr2);
}
#ifdef WITH_LUA
lua_handle_channel(channel, connection, text, type, luaevent_channel_userleft);
#endif
return 0;
}
@ -747,6 +757,10 @@ namespace pvpgn
if (!heard && (type == message_type_talk || type == message_type_emote))
message_send_text(me, message_type_info, me, "No one hears you.");
}
#ifdef WITH_LUA
lua_handle_channel((t_channel*)channel, me, text, type, luaevent_channel_message);
#endif
}
extern int channel_ban_user(t_channel * channel, char const * user)
@ -839,7 +853,7 @@ namespace pvpgn
eventlog(eventlog_level_error, __FUNCTION__, "got NULL user");
return -1;
}
if (!(channel->flags & channel_flags_allowbots) && conn_get_class(user) == conn_class_bot)
return 1;

View file

@ -132,6 +132,12 @@ namespace pvpgn
return;
}
#ifdef WITH_LUA
if (lua_handle_user(user_c, dest_c, text, luaevent_user_whisper) == 1)
return;
#endif
if (conn_get_dndstr(dest_c))
{
snprintf(msgtemp, sizeof(msgtemp), "%.64s is unavailable (%.128s)", conn_get_username(dest_c), conn_get_dndstr(dest_c));

View file

@ -740,6 +740,10 @@ namespace pvpgn
eventlog(eventlog_level_error, __FUNCTION__, "cannot sync account (sync_on_logoff)");
}
#ifdef WITH_LUA
lua_handle_user(c, NULL, NULL, luaevent_user_disconnect);
#endif
if (account_get_conn(c->protocol.account) == c) /* make sure you don't set this when allready on new conn (relogin with same account) */
account_set_conn(c->protocol.account, NULL);
c->protocol.account = NULL; /* the account code will free the memory later */
@ -2209,7 +2213,7 @@ namespace pvpgn
#ifdef WITH_LUA
// handle game create when it's owner joins the game
if (c == game_get_owner(c->protocol.game))
lua_handle_game(c->protocol.game, luaevent_game_create);
lua_handle_game(c->protocol.game, NULL, luaevent_game_create);
#endif
if (game_is_ladder(c->protocol.game)) {

View file

@ -476,7 +476,7 @@ namespace pvpgn
}
#ifdef WITH_LUA
lua_handle_game(game, luaevent_game_destroy);
lua_handle_game(game, NULL, luaevent_game_destroy);
#endif
elist_del(&game->glist_link);
@ -744,7 +744,7 @@ namespace pvpgn
}
#ifdef WITH_LUA
lua_handle_game(game, luaevent_game_end);
lua_handle_game(game, NULL, luaevent_game_end);
#endif
if (game->clienttag == CLIENTTAG_WARCRAFT3_UINT || game->clienttag == CLIENTTAG_WAR3XP_UINT)
@ -1111,7 +1111,7 @@ namespace pvpgn
std::fprintf(fp, "\nThis game lasted %lu minutes (elapsed).\n", ((unsigned long int)std::difftime(now, game->start_time)) / 60);
#ifdef WITH_LUA
lua_handle_game(game, luaevent_game_report);
lua_handle_game(game, NULL, luaevent_game_report);
#endif
if (std::fclose(fp) < 0)
@ -1454,7 +1454,7 @@ namespace pvpgn
game->status = status;
#ifdef WITH_LUA
lua_handle_game(game, luaevent_game_changestatus);
lua_handle_game(game, NULL, luaevent_game_changestatus);
#endif
}
@ -1750,7 +1750,7 @@ namespace pvpgn
game_choose_host(game);
#ifdef WITH_LUA
lua_handle_user(c, game, luaevent_user_leftgame);
lua_handle_game(game, c, luaevent_game_userleft);
#endif
return 0;
}

View file

@ -1738,6 +1738,12 @@ namespace pvpgn
}
}
if (success && account) {
#ifdef WITH_LUA
if (lua_handle_user(c, NULL, NULL, luaevent_user_login) == 1)
return 0;
#endif
#ifdef WIN32_GUI
guiOnUpdateUserList();
#endif
@ -3796,7 +3802,7 @@ namespace pvpgn
eventlog(eventlog_level_info, __FUNCTION__, "[%d] \"%s\" joined game \"%s\"", conn_get_socket(c), conn_get_username(c), gamename);
#ifdef WITH_LUA
lua_handle_user(c, game, luaevent_user_joingame);
lua_handle_game(game, c, luaevent_game_userjoin);
#endif
return 0;

View file

@ -15,12 +15,15 @@
* 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 "common/setup_before.h"
#include "command.h"
#include "team.h"
#include <cctype>
#include <cerrno>
@ -54,7 +57,6 @@
#include "message.h"
#include "channel.h"
#include "game.h"
#include "team.h"
#include "account.h"
#include "account_wrap.h"
#include "server.h"
@ -72,7 +74,6 @@
#include "topic.h"
#include "friends.h"
#include "clan.h"
#include "common/setup_after.h"
#include "common/flags.h"
#include "attrlayer.h"
@ -80,6 +81,10 @@
#include "luawrapper.h"
#include "luainterface.h"
#include "common/setup_after.h"
namespace pvpgn
{
@ -92,9 +97,11 @@ namespace pvpgn
std::map<std::string, std::string> get_account_object(t_account *account);
std::map<std::string, std::string> get_account_object(const char *username);
std::map<std::string, std::string> get_game_object(t_game * game);
// TODO:
//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_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>
@ -106,6 +113,9 @@ namespace pvpgn
int __account_get(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);
char _msgtemp[MAX_MESSAGE_LEN];
char _msgtemp2[MAX_MESSAGE_LEN];
@ -176,6 +186,9 @@ namespace pvpgn
vm.reg("account_get", __account_get);
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);
}
@ -193,9 +206,8 @@ namespace pvpgn
return 0;
std::map<std::string, std::string> o_account = get_account_object(account);
// invoke lua method
lua::transaction(vm) << lua::lookup("handle_command") << o_account << text << lua::invoke >> result << lua::end;
lua::transaction(vm) << lua::lookup("handle_command") << o_account << text << lua::invoke >> result << lua::end; // invoke lua function
}
catch (const std::exception& e)
{
@ -208,8 +220,11 @@ namespace pvpgn
return result;
}
extern void lua_handle_game(t_game * game, t_luaevent_type luaevent)
extern void lua_handle_game(t_game * game, t_connection * c, t_luaevent_type luaevent)
{
t_account * account;
const char * func_name;
switch (luaevent)
{
@ -228,13 +243,34 @@ namespace pvpgn
case luaevent_game_changestatus:
func_name = "handle_game_changestatus";
break;
case luaevent_game_userjoin:
func_name = "handle_game_userjoin";
break;
case luaevent_game_userleft:
func_name = "handle_game_userleft";
break;
default:
return;
}
try
{
std::map<std::string, std::string> o_game = get_game_object(game);
// invoke lua method
lua::transaction(vm) << lua::lookup(func_name) << o_game << lua::invoke << lua::end;
// handle_game_userjoin & handle_game_userleft
if (c)
{
if (!(account = conn_get_account(c)))
return;
std::map<std::string, std::string> o_account = get_account_object(account);
lua::transaction(vm) << lua::lookup(func_name) << o_game << o_account << lua::invoke << lua::end; // invoke lua function
}
// other functions
else
{
lua::transaction(vm) << lua::lookup(func_name) << o_game << lua::invoke << lua::end; // invoke lua function
}
}
catch (const std::exception& e)
{
@ -246,19 +282,24 @@ namespace pvpgn
}
}
extern void lua_handle_user(t_connection * c, t_game * game, t_luaevent_type luaevent)
extern void lua_handle_channel(t_channel * channel, t_connection * c, char const * message_text, t_message_type message_type, t_luaevent_type luaevent)
{
t_account * account;
const char * func_name;
switch (luaevent)
{
case luaevent_user_joingame:
func_name = "handle_user_joingame";
case luaevent_channel_message:
func_name = "handle_channel_message";
break;
case luaevent_user_leftgame:
func_name = "handle_user_leftgame";
case luaevent_channel_userjoin:
func_name = "handle_channel_userjoin";
break;
case luaevent_channel_userleft:
func_name = "handle_channel_userleft";
break;
default:
return;
}
try
{
@ -266,9 +307,14 @@ namespace pvpgn
return;
std::map<std::string, std::string> o_account = get_account_object(account);
std::map<std::string, std::string> o_game = get_game_object(game);
std::map<std::string, std::string> o_channel = get_channel_object(channel);
lua::transaction(vm) << lua::lookup("handle_user_leftgame") << o_account << o_game << lua::invoke << lua::end;
// handle_channel_userleft & handle_channel_message
if (message_text)
lua::transaction(vm) << lua::lookup(func_name) << o_channel << o_account << message_text << message_type << lua::invoke << lua::end; // invoke lua function
// other functions
else
lua::transaction(vm) << lua::lookup(func_name) << o_channel << o_account << lua::invoke << lua::end; // invoke lua function
}
catch (const std::exception& e)
{
@ -280,6 +326,57 @@ namespace pvpgn
}
}
extern int lua_handle_user(t_connection * c, t_connection * c_dst, char const * message_text, t_luaevent_type luaevent)
{
t_account * account, *account_dst;
const char * func_name;
int result = 0;
switch (luaevent)
{
case luaevent_user_whisper:
func_name = "handle_user_whisper";
break;
case luaevent_user_login:
func_name = "handle_user_login";
break;
case luaevent_user_disconnect:
func_name = "handle_user_disconnect";
break;
default:
return 0;
}
try
{
if (!(account = conn_get_account(c)))
return 0;
std::map<std::string, std::string> o_account = get_account_object(account);
// handle_server_whisper
if (c_dst && message_text)
{
if (!(account_dst = conn_get_account(c_dst)))
return 0;
std::map<std::string, std::string> o_account_dst = get_account_object(account_dst);
lua::transaction(vm) << lua::lookup(func_name) << o_account << o_account_dst << message_text << lua::invoke >> result << lua::end; // invoke lua function
}
// other functions
else
lua::transaction(vm) << lua::lookup(func_name) << o_account << lua::invoke << lua::end; // invoke lua function
}
catch (const std::exception& e)
{
eventlog(eventlog_level_error, __FUNCTION__, e.what());
}
catch (...)
{
eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n");
}
return result;
}
#endif
/* --- Lua Functions (called from scripts) */
@ -484,7 +581,6 @@ namespace pvpgn
break;
}
}
st.push(result);
}
catch (const std::exception& e)
@ -495,10 +591,133 @@ namespace pvpgn
{
eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n");
}
return 1;
}
/* Get account friend list */
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 account team list */
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)
{
int clan_id;
std::vector<std::map<std::string, std::string>> members;
try
{
lua::stack st(L);
// get args
st.at(1, clan_id);
if (t_clan * clan = clanlist_find_clan_by_clanid(clan_id))
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;
}
// TODO: remove it
/* Just a test function */
int _sum(lua_State* L)
@ -520,7 +739,7 @@ namespace pvpgn
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))
return get_account_object(account);
else
@ -554,6 +773,12 @@ namespace pvpgn
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;
}
@ -631,7 +856,149 @@ namespace pvpgn
return o_game;
}
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 */

View file

@ -45,22 +45,16 @@ namespace pvpgn
luaevent_game_end,
luaevent_game_destroy,
luaevent_game_changestatus,
luaevent_game_userjoin,
luaevent_game_userleft,
luaevent_channel_create,
luaevent_channel_destroy,
luaevent_channel_message, // user-to-channel
luaevent_channel_userjoin,
luaevent_channel_userleft,
luaevent_user_joingame,
luaevent_user_leftgame,
luaevent_user_joinchannel,
luaevent_user_leftchannel,
luaevent_user_joinclan,
luaevent_user_leftclan,
luaevent_clan_userjoin,
luaevent_clan_userleft,
luaevent_clan_create,
luaevent_clan_changestatus,
luaevent_clan_destroy,
luaevent_user_message, // user-to-channel
luaevent_user_whisper, // user-to-user
luaevent_user_login,
luaevent_user_disconnect
@ -72,9 +66,11 @@ namespace pvpgn
extern void lua_unload();
extern int lua_handle_command(t_connection * c, char const * text);
extern void lua_handle_game(t_game * game, t_luaevent_type luaevent); // game events
extern void lua_handle_user(t_connection * c, t_game * game, t_luaevent_type luaevent); //
// TODO:
extern void lua_handle_game(t_game * game, t_connection * c, t_luaevent_type luaevent);
extern void lua_handle_channel(t_channel * channel, t_connection * c, char const * message_text, t_message_type message_type, t_luaevent_type luaevent);
extern int lua_handle_user(t_connection * c, t_connection * c_dst, char const * message_text, t_luaevent_type luaevent);
// TODO:
//extern void lua_handle_user(t_connection * c, t_connection * c_dst, const char * text, t_luaevent_type luaevent);
//extern void lua_handle_user(t_connection * c, t_channel * channel, const char * text, t_luaevent_type luaevent);
//extern void lua_handle_user(t_connection * c, t_channel * channel, t_luaevent_type luaevent);

View file

@ -163,6 +163,9 @@ namespace pvpgn
class dirent *ent;
dir = opendir(directory);
if (!dir)
return files;
while ((ent = readdir(dir)) != NULL) {
const std::string file_name = ent->d_name;
const std::string full_file_name = std::string(directory) + "/" + file_name;