1
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
11
#include "Game/UI/LuaUI.h"
12
#include "LuaCallInCheck.h"
13
#include "LuaHandle.h"
14
#include "LuaHashString.h"
18
#define REGISTER_LUA_CFUNC(x) \
19
lua_pushstring(L, #x); \
20
lua_pushcfunction(L, x); \
24
inline LuaLobby* toLuaLobby(lua_State* L, int idx)
26
LuaLobby** lob = (LuaLobby**)luaL_checkudata(L, idx, "LuaLobby");
28
luaL_error(L, "Attempt to use a deleted LuaLobby object!");
34
/******************************************************************************/
35
/******************************************************************************/
37
LuaLobby::LuaLobby(lua_State* _L) : L(_L)
40
luaL_error(L, "Tried to create a LuaLobby object in a non-LuaUI enviroment!");
48
/******************************************************************************/
49
/******************************************************************************/
51
bool LuaLobby::PushEntries(lua_State* L)
55
REGISTER_LUA_CFUNC(CreateLobby);
60
bool LuaLobby::CreateMetatable(lua_State* L)
62
luaL_newmetatable(L, "LuaLobby");
63
HSTR_PUSH_CFUNC(L, "__gc", meta_gc);
64
HSTR_PUSH_CFUNC(L, "__index", meta_index);
65
HSTR_PUSH_CFUNC(L, "__newindex", meta_newindex);
66
LuaPushNamedString(L, "__metatable", "protected metatable");
68
REGISTER_LUA_CFUNC(Poll);
69
REGISTER_LUA_CFUNC(Connect);
70
REGISTER_LUA_CFUNC(Disconnect);
71
REGISTER_LUA_CFUNC(Register);
72
REGISTER_LUA_CFUNC(Login);
73
REGISTER_LUA_CFUNC(ConfirmAggreement);
74
REGISTER_LUA_CFUNC(Rename);
75
REGISTER_LUA_CFUNC(ChangePass);
76
REGISTER_LUA_CFUNC(StatusUpdate);
77
REGISTER_LUA_CFUNC(Channels);
78
REGISTER_LUA_CFUNC(RequestMutelist);
79
REGISTER_LUA_CFUNC(JoinChannel);
80
REGISTER_LUA_CFUNC(LeaveChannel);
81
REGISTER_LUA_CFUNC(KickChannelMember);
82
REGISTER_LUA_CFUNC(ChangeTopic);
83
REGISTER_LUA_CFUNC(Say);
84
REGISTER_LUA_CFUNC(SayEx);
85
REGISTER_LUA_CFUNC(SayPrivate);
91
/******************************************************************************/
92
/******************************************************************************/
94
int LuaLobby::CreateLobby(lua_State* L)
96
LuaLobby* lob = new LuaLobby(L);
98
LuaLobby** lobPtr = (LuaLobby**)lua_newuserdata(L, sizeof(LuaLobby*));
101
luaL_getmetatable(L, "LuaLobby");
102
lua_setmetatable(L, -2);
105
lob->luaRefEvents = luaL_ref(L, LUA_REGISTRYINDEX);
106
if (lob->luaRefEvents == LUA_NOREF) {
114
lob->luaRef = luaL_ref(L, LUA_REGISTRYINDEX);
115
if (lob->luaRef == LUA_NOREF) {
125
/******************************************************************************/
126
/******************************************************************************/
128
int LuaLobby::meta_gc(lua_State* L)
130
//FIXME: this might never get called because we hold a link to the userdata object in LUA_REGISTRYINDEX
132
LuaLobby* lob = toLuaLobby(L, 1);
134
luaL_unref(L, LUA_REGISTRYINDEX, lob->luaRef);
135
luaL_unref(L, LUA_REGISTRYINDEX, lob->luaRefEvents);
141
int LuaLobby::meta_index(lua_State* L)
143
//! check if there is a function
144
luaL_getmetatable(L, "LuaLobby");
147
if (!lua_isnil(L, -1)) {
152
LuaLobby* lob = toLuaLobby(L, 1);
153
lua_rawgeti(L, LUA_REGISTRYINDEX, lob->luaRefEvents);
156
if (!lua_isnil(L, -1)) {
164
int LuaLobby::meta_newindex(lua_State* L)
166
//if (!lua_isfunction(L, 3)) {
167
// luaL_error(L, "tried to set non-function!");
170
LuaLobby* lob = toLuaLobby(L, 1);
171
lua_rawgeti(L, LUA_REGISTRYINDEX, lob->luaRefEvents);
172
lua_pushvalue(L, 2); // name
173
lua_pushvalue(L, 3); // function
179
/******************************************************************************/
180
/******************************************************************************/
182
inline bool LuaLobby::PushCallIn(const LuaHashString& name)
184
// get callin lua function
185
lua_rawgeti(L, LUA_REGISTRYINDEX, luaRefEvents);
189
// check if the function is valid/set
190
if (lua_isfunction(L, -1)) {
197
/******************************************************************************/
198
/******************************************************************************/
200
int LuaLobby::Poll(lua_State *L)
202
LuaLobby* lob = toLuaLobby(L, 1);
207
int LuaLobby::Connect(lua_State *L)
209
LuaLobby* lob = toLuaLobby(L, 1);
210
std::string host(luaL_checkstring(L, 2));
211
int port = luaL_checknumber(L, 3);
212
lob->Connect(host, port);
216
int LuaLobby::Disconnect(lua_State *L)
218
LuaLobby* lob = toLuaLobby(L, 1);
223
int LuaLobby::Register(lua_State *L)
225
LuaLobby* lob = toLuaLobby(L, 1);
226
std::string user(luaL_checkstring(L, 2));
227
std::string pass(luaL_checkstring(L, 3));
228
lob->Register(user, pass);
232
int LuaLobby::Login(lua_State *L)
234
LuaLobby* lob = toLuaLobby(L, 1);
235
std::string user(luaL_checkstring(L, 2));
236
std::string pass(luaL_checkstring(L, 3));
237
lob->Login(user, pass);
241
int LuaLobby::ConfirmAggreement(lua_State *L)
243
LuaLobby* lob = toLuaLobby(L, 1);
244
lob->ConfirmAggreement();
248
int LuaLobby::Rename(lua_State *L)
250
LuaLobby* lob = toLuaLobby(L, 1);
251
std::string newname(luaL_checkstring(L, 2));
252
lob->Rename(newname);
256
int LuaLobby::ChangePass(lua_State *L)
258
LuaLobby* lob = toLuaLobby(L, 1);
259
std::string oldpass(luaL_checkstring(L, 2));
260
std::string newpass(luaL_checkstring(L, 3));
261
lob->ChangePass(oldpass, newpass);
265
int LuaLobby::StatusUpdate(lua_State *L)
267
LuaLobby* lob = toLuaLobby(L, 1);
268
bool ingame = lua_toboolean(L, 2);
269
bool away = lua_toboolean(L, 3);
270
lob->StatusUpdate(ingame, away);
274
int LuaLobby::Channels(lua_State *L)
276
LuaLobby* lob = toLuaLobby(L, 1);
281
int LuaLobby::RequestMutelist(lua_State *L)
283
LuaLobby* lob = toLuaLobby(L, 1);
284
std::string channame(luaL_checkstring(L, 2));
285
lob->RequestMutelist(channame);
289
int LuaLobby::JoinChannel(lua_State *L)
291
LuaLobby* lob = toLuaLobby(L, 1);
292
std::string channame(luaL_checkstring(L, 2));
293
std::string passwd = "";
294
if (lua_isstring(L, 3))
295
passwd = luaL_checkstring(L, 3);
296
lob->JoinChannel(channame, passwd);
300
int LuaLobby::LeaveChannel(lua_State *L)
302
LuaLobby* lob = toLuaLobby(L, 1);
303
std::string channame(luaL_checkstring(L, 2));
304
lob->LeaveChannel(channame);
308
int LuaLobby::ChangeTopic(lua_State *L)
310
LuaLobby* lob = toLuaLobby(L, 1);
311
std::string channame(luaL_checkstring(L, 2));
312
std::string topic(luaL_checkstring(L, 3));
313
lob->ChangeTopic(channame, topic);
317
int LuaLobby::Say(lua_State *L)
319
LuaLobby* lob = toLuaLobby(L, 1);
320
std::string channame(luaL_checkstring(L, 2));
321
std::string message(luaL_checkstring(L, 3));
322
lob->Say(channame, message);
326
int LuaLobby::SayEx(lua_State *L)
328
LuaLobby* lob = toLuaLobby(L, 1);
329
std::string channame(luaL_checkstring(L, 2));
330
std::string message(luaL_checkstring(L, 3));
331
lob->SayEx(channame, message);
335
int LuaLobby::SayPrivate(lua_State *L)
337
LuaLobby* lob = toLuaLobby(L, 1);
338
std::string username(luaL_checkstring(L, 2));
339
std::string message(luaL_checkstring(L, 3));
340
lob->SayPrivate(username, message);
344
int LuaLobby::KickChannelMember(lua_State *L)
346
LuaLobby* lob = toLuaLobby(L, 1);
347
std::string channame(luaL_checkstring(L, 2));
348
std::string user(luaL_checkstring(L, 3));
349
std::string reason(luaL_checkstring(L, 4));
350
lob->KickChannelMember(channame, user, reason);
354
/******************************************************************************/
355
/******************************************************************************/
357
void LuaLobby::DoneConnecting(bool succes, const std::string& err)
359
LUA_CALL_IN_CHECK(L);
360
lua_checkstack(L, 4);
361
static const LuaHashString cmdStr(__FUNCTION__);
362
if (!PushCallIn(cmdStr)) {
366
lua_pushboolean(L, succes);
367
lua_pushstring(L, err.c_str());
370
luaUI->RunCallInUnsynced(cmdStr, 2, 0);
373
void LuaLobby::ServerGreeting(const std::string& serverVer, const std::string& springVer, int udpport, int mode)
375
LUA_CALL_IN_CHECK(L);
376
lua_checkstack(L, 6);
377
static const LuaHashString cmdStr(__FUNCTION__);
378
if (!PushCallIn(cmdStr)) {
382
lua_pushstring(L, serverVer.c_str());
383
lua_pushstring(L, springVer.c_str());
384
lua_pushnumber(L, udpport);
385
lua_pushnumber(L, mode);
388
luaUI->RunCallInUnsynced(cmdStr, 4, 0);
391
void LuaLobby::RegisterDenied(const std::string& reason)
393
LUA_CALL_IN_CHECK(L);
394
lua_checkstack(L, 3);
395
static const LuaHashString cmdStr(__FUNCTION__);
396
if (!PushCallIn(cmdStr)) {
400
lua_pushstring(L, reason.c_str());
403
luaUI->RunCallInUnsynced(cmdStr, 1, 0);
406
void LuaLobby::RegisterAccepted()
408
LUA_CALL_IN_CHECK(L);
409
lua_checkstack(L, 2);
410
static const LuaHashString cmdStr(__FUNCTION__);
411
if (!PushCallIn(cmdStr)) {
416
luaUI->RunCallInUnsynced(cmdStr, 0, 0);
419
void LuaLobby::LoginDenied(const std::string& reason)
421
LUA_CALL_IN_CHECK(L);
422
lua_checkstack(L, 3);
423
static const LuaHashString cmdStr(__FUNCTION__);
424
if (!PushCallIn(cmdStr)) {
428
lua_pushstring(L, reason.c_str());
431
luaUI->RunCallInUnsynced(cmdStr, 1, 0);
434
void LuaLobby::LoginEnd()
436
LUA_CALL_IN_CHECK(L);
437
lua_checkstack(L, 2);
438
static const LuaHashString cmdStr(__FUNCTION__);
439
if (!PushCallIn(cmdStr)) {
444
luaUI->RunCallInUnsynced(cmdStr, 0, 0);
447
void LuaLobby::Aggreement(const std::string& text)
449
LUA_CALL_IN_CHECK(L);
450
lua_checkstack(L, 3);
451
static const LuaHashString cmdStr(__FUNCTION__);
452
if (!PushCallIn(cmdStr)) {
456
lua_pushstring(L, text.c_str());
459
luaUI->RunCallInUnsynced(cmdStr, 1, 0);
462
void LuaLobby::Motd(const std::string& text)
464
LUA_CALL_IN_CHECK(L);
465
lua_checkstack(L, 3);
466
static const LuaHashString cmdStr(__FUNCTION__);
467
if (!PushCallIn(cmdStr)) {
471
lua_pushstring(L, text.c_str());
474
luaUI->RunCallInUnsynced(cmdStr, 1, 0);
477
void LuaLobby::ServerMessage(const std::string& text)
479
LUA_CALL_IN_CHECK(L);
480
lua_checkstack(L, 3);
481
static const LuaHashString cmdStr(__FUNCTION__);
482
if (!PushCallIn(cmdStr)) {
486
lua_pushstring(L, text.c_str());
489
luaUI->RunCallInUnsynced(cmdStr, 1, 0);
492
void LuaLobby::ServerMessageBox(const std::string& text, const std::string& url)
494
LUA_CALL_IN_CHECK(L);
495
lua_checkstack(L, 4);
496
static const LuaHashString cmdStr(__FUNCTION__);
497
if (!PushCallIn(cmdStr)) {
501
lua_pushstring(L, text.c_str());
502
lua_pushstring(L, url.c_str());
505
luaUI->RunCallInUnsynced(cmdStr, 2, 0);
508
void LuaLobby::AddUser(const std::string& name, const std::string& country, int cpu)
510
LUA_CALL_IN_CHECK(L);
511
lua_checkstack(L, 5);
512
static const LuaHashString cmdStr(__FUNCTION__);
513
if (!PushCallIn(cmdStr)) {
517
lua_pushstring(L, name.c_str());
518
lua_pushstring(L, country.c_str());
519
lua_pushnumber(L, cpu);
522
luaUI->RunCallInUnsynced(cmdStr, 3, 0);
525
void LuaLobby::RemoveUser(const std::string& name)
527
LUA_CALL_IN_CHECK(L);
528
lua_checkstack(L, 3);
529
static const LuaHashString cmdStr(__FUNCTION__);
530
if (!PushCallIn(cmdStr)) {
534
lua_pushstring(L, name.c_str());
537
luaUI->RunCallInUnsynced(cmdStr, 1, 0);
540
void LuaLobby::UserStatusUpdate(const std::string& name, ClientStatus status)
542
LUA_CALL_IN_CHECK(L);
543
lua_checkstack(L, 8);
544
static const LuaHashString cmdStr(__FUNCTION__);
545
if (!PushCallIn(cmdStr)) {
549
lua_pushstring(L, name.c_str());
550
lua_pushboolean(L, status.away);
551
lua_pushboolean(L, status.bot);
552
lua_pushboolean(L, status.ingame);
553
lua_pushboolean(L, status.moderator);
554
lua_pushnumber(L, status.rank);
557
luaUI->RunCallInUnsynced(cmdStr, 6, 0);
560
void LuaLobby::ChannelInfo(const std::string& channel, unsigned users)
562
LUA_CALL_IN_CHECK(L);
563
lua_checkstack(L, 4);
564
static const LuaHashString cmdStr(__FUNCTION__);
565
if (!PushCallIn(cmdStr)) {
569
lua_pushstring(L, channel.c_str());
570
lua_pushnumber(L, users);
573
luaUI->RunCallInUnsynced(cmdStr, 2, 0);
576
void LuaLobby::ChannelInfoEnd()
578
LUA_CALL_IN_CHECK(L);
579
lua_checkstack(L, 2);
580
static const LuaHashString cmdStr(__FUNCTION__);
581
if (!PushCallIn(cmdStr)) {
586
luaUI->RunCallInUnsynced(cmdStr, 0, 0);
589
void LuaLobby::Mutelist(const std::string& channel, std::list<std::string> list)
591
LUA_CALL_IN_CHECK(L);
592
lua_checkstack(L, 4);
593
static const LuaHashString cmdStr(__FUNCTION__);
594
if (!PushCallIn(cmdStr)) {
598
lua_pushstring(L, channel.c_str());
601
for (std::list<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
603
lua_pushstring(L, it->c_str());
604
lua_rawseti(L, -2, i++);
608
luaUI->RunCallInUnsynced(cmdStr, 2, 0);
611
void LuaLobby::Joined(const std::string& channame)
613
LUA_CALL_IN_CHECK(L);
614
lua_checkstack(L, 3);
615
static const LuaHashString cmdStr(__FUNCTION__);
616
if (!PushCallIn(cmdStr)) {
620
lua_pushstring(L, channame.c_str());
623
luaUI->RunCallInUnsynced(cmdStr, 1, 0);
626
void LuaLobby::ChannelMember(const std::string& channame, const std::string& name, bool joined)
628
LUA_CALL_IN_CHECK(L);
629
lua_checkstack(L, 5);
630
static const LuaHashString cmdStr(__FUNCTION__);
631
if (!PushCallIn(cmdStr)) {
635
lua_pushstring(L, channame.c_str());
636
lua_pushstring(L, name.c_str());
637
lua_pushboolean(L, joined);
640
luaUI->RunCallInUnsynced(cmdStr, 3, 0);
643
void LuaLobby::ChannelMemberLeft(const std::string& channame, const std::string& name, const std::string& reason)
645
LUA_CALL_IN_CHECK(L);
646
lua_checkstack(L, 5);
647
static const LuaHashString cmdStr(__FUNCTION__);
648
if (!PushCallIn(cmdStr)) {
652
lua_pushstring(L, channame.c_str());
653
lua_pushstring(L, name.c_str());
654
lua_pushstring(L, reason.c_str());
657
luaUI->RunCallInUnsynced(cmdStr, 3, 0);
660
void LuaLobby::JoinFailed(const std::string& channame, const std::string& reason)
662
LUA_CALL_IN_CHECK(L);
663
lua_checkstack(L, 4);
664
static const LuaHashString cmdStr(__FUNCTION__);
665
if (!PushCallIn(cmdStr)) {
669
lua_pushstring(L, channame.c_str());
670
lua_pushstring(L, reason.c_str());
673
luaUI->RunCallInUnsynced(cmdStr, 2, 0);
676
void LuaLobby::ChannelMemberKicked(const std::string& channame, const std::string& user, const std::string& reason)
678
LUA_CALL_IN_CHECK(L);
679
lua_checkstack(L, 5);
680
static const LuaHashString cmdStr(__FUNCTION__);
681
if (!PushCallIn(cmdStr)) {
685
lua_pushstring(L, channame.c_str());
686
lua_pushstring(L, user.c_str());
687
lua_pushstring(L, reason.c_str());
690
luaUI->RunCallInUnsynced(cmdStr, 3, 0);
693
void LuaLobby::ChannelTopic(const std::string& channame, const std::string& author, long unsigned time, const std::string& topic)
695
LUA_CALL_IN_CHECK(L);
696
lua_checkstack(L, 6);
697
static const LuaHashString cmdStr(__FUNCTION__);
698
if (!PushCallIn(cmdStr)) {
702
lua_pushstring(L, channame.c_str());
703
lua_pushstring(L, author.c_str());
704
lua_pushnumber(L, time/1000);
705
lua_pushstring(L, topic.c_str());
708
luaUI->RunCallInUnsynced(cmdStr, 4, 0);
711
void LuaLobby::ChannelMessage(const std::string& channel, const std::string& text)
713
LUA_CALL_IN_CHECK(L);
714
lua_checkstack(L, 4);
715
static const LuaHashString cmdStr(__FUNCTION__);
716
if (!PushCallIn(cmdStr)) {
720
lua_pushstring(L, channel.c_str());
721
lua_pushstring(L, text.c_str());
724
luaUI->RunCallInUnsynced(cmdStr, 2, 0);
727
void LuaLobby::Said(const std::string& channel, const std::string& user, const std::string& text)
729
LUA_CALL_IN_CHECK(L);
730
lua_checkstack(L, 5);
731
static const LuaHashString cmdStr(__FUNCTION__);
732
if (!PushCallIn(cmdStr)) {
736
lua_pushstring(L, channel.c_str());
737
lua_pushstring(L, user.c_str());
738
lua_pushstring(L, text.c_str());
741
luaUI->RunCallInUnsynced(cmdStr, 3, 0);
744
void LuaLobby::SaidEx(const std::string& channel, const std::string& user, const std::string& text)
746
LUA_CALL_IN_CHECK(L);
747
lua_checkstack(L, 5);
748
static const LuaHashString cmdStr(__FUNCTION__);
749
if (!PushCallIn(cmdStr)) {
753
lua_pushstring(L, channel.c_str());
754
lua_pushstring(L, user.c_str());
755
lua_pushstring(L, text.c_str());
758
luaUI->RunCallInUnsynced(cmdStr, 3, 0);
761
void LuaLobby::SaidPrivate(const std::string& user, const std::string& text)
763
LUA_CALL_IN_CHECK(L);
764
lua_checkstack(L, 4);
765
static const LuaHashString cmdStr(__FUNCTION__);
766
if (!PushCallIn(cmdStr)) {
770
lua_pushstring(L, user.c_str());
771
lua_pushstring(L, text.c_str());
774
luaUI->RunCallInUnsynced(cmdStr, 2, 0);
777
void LuaLobby::Disconnected()
779
LUA_CALL_IN_CHECK(L);
780
lua_checkstack(L, 2);
781
static const LuaHashString cmdStr(__FUNCTION__);
782
if (!PushCallIn(cmdStr)) {
787
luaUI->RunCallInUnsynced(cmdStr, 0, 0);
790
void LuaLobby::NetworkError(const std::string& msg)
792
LUA_CALL_IN_CHECK(L);
793
lua_checkstack(L, 3);
794
static const LuaHashString cmdStr(__FUNCTION__);
795
if (!PushCallIn(cmdStr)) {
799
lua_pushstring(L, msg.c_str());
802
luaUI->RunCallInUnsynced(cmdStr, 1, 0);
805
/******************************************************************************/
806
/******************************************************************************/