Skip to content
This repository
Browse code

* Competition Mode fuer infond. startet ein oder mehrere Bots und la…

…esst sie in vorgegebenen Karten gegeneinander laufen.

 * Listener kann deaktiviert und neu gebind()et werden
 * diverser Kleinkram


git-svn-id: http://infon.googlecode.com/svn/trunk@134 8171fb75-e542-0410-96e4-03d5dd800671
  • Loading branch information...
commit a8e15a2910ed53c63837dbf0847b67735701344d 1 parent 6e63902
Florian Wesch authored
11 config.lua
@@ -49,3 +49,14 @@ banner = [[
49 49 ~~`---' / |
50 50 ,-' _/'
51 51 ]] -- von http://www.asciiworld.com/animals_birds.html
  52 +
  53 +-- competition = true
  54 +-- competition_log = "competition.log"
  55 +-- competition_bots = { "bot1.lua", "bot2.lua" }
  56 +-- time_limit = 10 * 60 * 1000
  57 +-- maps = { "foo", "foo", "foo" }
  58 +-- listenaddr = nil
  59 +
  60 +-- function autoexec()
  61 +-- start_bot("bot1.lua")
  62 +-- end
2  creature.c
@@ -1021,9 +1021,7 @@ void creature_init() {
1021 1021 creature_t *creature = &creatures[i];
1022 1022 creature->player = NULL;
1023 1023 }
1024   -}
1025 1024
1026   -void creature_game_start() {
1027 1025 next_free_vm_id = 0;
1028 1026 }
1029 1027
1  creature.h
@@ -101,7 +101,6 @@ void creature_send_initial_update(client_t *client);
101 101 void creature_to_network(creature_t *creature, int dirtymask, client_t *client);
102 102
103 103 void creature_init();
104   -void creature_game_start();
105 104 void creature_shutdown();
106 105
107 106 #endif
2  demo2graph.rb
@@ -199,7 +199,7 @@ def dump_world
199 199
200 200 infon = InfonDemo.new(ARGV[0])
201 201 while infon.tick
202   - #print "%2d:%02d " % [infon.time / 1000 / 60, infon.time / 1000 % 60]
  202 + print "%2d:%02d " % [infon.time / 1000 / 60, infon.time / 1000 % 60]
203 203 #puts "%d %d" % [infon.players.size, infon.creatures.size]
204 204 20.times do |i|
205 205 if creature = infon.creatures[i]
86 game.c
@@ -32,13 +32,14 @@
32 32 #include "misc.h"
33 33
34 34 static int should_end_game = 0;
35   -static struct timeval start;
  35 +static struct timeval server_start, game_start;
36 36 static char intermission[256] = {0};
  37 +static int realtime = 1;
37 38
38   -static int get_tick() {
39   - static struct timeval now;
  39 +static int get_tick(const struct timeval *ref) {
  40 + struct timeval now;
40 41 gettimeofday(&now , NULL);
41   - return (now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec - start.tv_usec) / 1000;
  42 + return (now.tv_sec - ref->tv_sec) * 1000 + (now.tv_usec - ref->tv_usec) / 1000;
42 43 }
43 44
44 45 void game_send_info(client_t *client) {
@@ -84,15 +85,13 @@ static int luaGameEnd(lua_State *L) {
84 85 return 0;
85 86 }
86 87
87   -static int luaGameInfo(lua_State *L) {
  88 +static int luaGameTime(lua_State *L) {
88 89 lua_pushnumber(L, game_time);
89   - lua_pushnumber(L, world_width());
90   - lua_pushnumber(L, world_height());
91   - return 3;
  90 + return 1;
92 91 }
93 92
94   -static int luaGameTime(lua_State *L) {
95   - lua_pushnumber(L, game_time);
  93 +static int luaRealTime(lua_State *L) {
  94 + lua_pushnumber(L, real_time);
96 95 return 1;
97 96 }
98 97
@@ -106,6 +105,11 @@ static int luaShutdown(lua_State *L) {
106 105 return 0;
107 106 }
108 107
  108 +static int luaSetRealtime(lua_State *L) {
  109 + realtime = lua_toboolean(L, 1);
  110 + return 0;
  111 +}
  112 +
109 113 static int luaGameIntermission(lua_State *L) {
110 114 snprintf(intermission, sizeof(intermission), "%s", luaL_checkstring(L, 1));
111 115 game_send_intermission(SEND_BROADCAST);
@@ -146,30 +150,32 @@ static int luaHexDecode(lua_State *L) {
146 150 }
147 151
148 152 void game_init() {
  153 + gettimeofday(&server_start, NULL);
  154 +
149 155 lua_register(L, "game_end", luaGameEnd);
150   - lua_register(L, "game_info", luaGameInfo);
151 156 lua_register(L, "game_time", luaGameTime);
  157 + lua_register(L, "real_time", luaRealTime);
152 158
153 159 lua_register(L, "set_intermission", luaGameIntermission);
154 160
155 161 lua_register(L, "scroller_add", luaScrollerAdd);
156 162
157 163 lua_register(L, "hex_decode", luaHexDecode);
  164 + lua_register(L, "set_realtime", luaSetRealtime);
158 165 lua_register(L, "shutdown", luaShutdown);
159 166
160   - lua_pushnumber(L, MAXPLAYERS);
161   - lua_setglobal(L, "MAXPLAYERS");
162   -
163   - lua_pushliteral(L, GAME_NAME);
164   - lua_setglobal(L, "GAME_NAME");
  167 + lua_register_constant (L, MAXPLAYERS);
  168 + lua_register_string_constant(L, GAME_NAME);
165 169 }
166 170
167 171 void game_one_game() {
168 172 should_end_game = 0;
169 173 game_time = 0;
170 174
  175 + // Zeitinfo an Client
171 176 game_send_info(SEND_BROADCAST);
172 177
  178 + // Regeln laden
173 179 lua_pushliteral(L, "rules_init");
174 180 lua_rawget(L, LUA_GLOBALSINDEX);
175 181 if (lua_pcall(L, 0, 0, 0) != 0) {
@@ -177,7 +183,10 @@ void game_one_game() {
177 183 lua_pop(L, 1);
178 184 }
179 185
  186 + // Karte laden
180 187 world_init();
  188 +
  189 + // Alle Viecher tot. vm_id = 0
181 190 creature_init();
182 191
183 192 // Initialer Worldtick. ruft level_init und ersten level_tick auf.
@@ -185,17 +194,16 @@ void game_one_game() {
185 194
186 195 // Beginn der Zeitrechnung...
187 196 int lasttick = 0;
188   - gettimeofday(&start, NULL);
  197 + gettimeofday(&game_start, NULL);
189 198
190   - creature_game_start();
191   - server_game_start();
  199 + // onPlayerCreated Event an Rules, PLAYER_CREATED an VM
192 200 player_game_start();
193 201
194 202 // Spiel gestartet
195   - lua_pushliteral(L, "new_game_started");
  203 + lua_pushliteral(L, "on_game_started");
196 204 lua_rawget(L, LUA_GLOBALSINDEX);
197 205 if (lua_pcall(L, 0, 0, 0) != 0) {
198   - fprintf(stderr, "error calling new_game_started: %s\n", lua_tostring(L, -1));
  206 + fprintf(stderr, "error calling on_game_started: %s\n", lua_tostring(L, -1));
199 207 lua_pop(L, 1);
200 208 }
201 209
@@ -203,19 +211,25 @@ void game_one_game() {
203 211 game_call_rule_handler("onNewGame", 0);
204 212
205 213 while (!game_exit && !should_end_game) {
206   - int tick = get_tick();
207   - int delta = tick - lasttick;
208   -
209   - if (delta < 0 || delta > 200) {
210   - // Timewarp?
211   - lasttick = tick;
212   - continue;
213   - } else if (delta < 100) {
214   - usleep(max(95000 - delta * 1000, 1000));
215   - continue;
  214 + int tick = get_tick(&game_start);
  215 + int delta;
  216 + if (realtime) {
  217 + delta = tick - lasttick;
  218 + if (delta < 0 || delta > 200) {
  219 + // Timewarp?
  220 + lasttick = tick;
  221 + continue;
  222 + } else if (delta < 100) {
  223 + usleep(max(95000 - delta * 1000, 1000));
  224 + continue;
  225 + }
  226 + } else {
  227 + delta = 100;
216 228 }
217   -
218 229 lasttick = tick;
  230 +
  231 + // Realtime update
  232 + real_time = get_tick(&server_start);
219 233
220 234 // GC
221 235 lua_gc(L, LUA_GCSTEP, 1);
@@ -244,6 +258,14 @@ void game_one_game() {
244 258 server_tick();
245 259 }
246 260
  261 + // Spiel beendet
  262 + lua_pushliteral(L, "on_game_ended");
  263 + lua_rawget(L, LUA_GLOBALSINDEX);
  264 + if (lua_pcall(L, 0, 0, 0) != 0) {
  265 + fprintf(stderr, "error calling on_game_ended: %s\n", lua_tostring(L, -1));
  266 + lua_pop(L, 1);
  267 + }
  268 +
247 269 server_game_end();
248 270
249 271 creature_shutdown();
12 infond.c
@@ -45,6 +45,7 @@
45 45
46 46 lua_State *L;
47 47
  48 +int real_time = 0;
48 49 int game_time = 0;
49 50 int game_paused = 0;
50 51 int game_exit = 0;
@@ -71,13 +72,18 @@ int main(int argc, char *argv[]) {
71 72 luaL_openlibs(L);
72 73
73 74 lua_register_string_constant(L, PREFIX);
74   -
75   - if (luaL_dofile(L, PREFIX "infond.lua"))
76   - die("cannot read 'infond.lua': %s", lua_tostring(L, -1));
77 75
78 76 game_init();
79 77 server_init();
80 78 player_init();
  79 +
  80 + if (luaL_dofile(L, PREFIX "infond.lua"))
  81 + die("cannot execute 'infond.lua': %s", lua_tostring(L, -1));
  82 +
  83 + // XXX: HACK: stdin client starten
  84 +#ifndef NO_CONSOLE_CLIENT
  85 + server_accept(STDIN_FILENO, "special:console");
  86 +#endif
81 87
82 88 #ifdef DAEMONIZING
83 89 daemonize(argc, argv);
1  infond.h
@@ -25,6 +25,7 @@
25 25
26 26 extern lua_State *L;
27 27
  28 +extern int real_time;
28 29 extern int game_time;
29 30 extern int game_paused;
30 31 extern int game_exit;
135 infond.lua
@@ -30,7 +30,6 @@ stats = {
30 30 num_players = 0;
31 31 num_maps = 0;
32 32 num_exec = 0;
33   - start_time = os.time();
34 33 }
35 34
36 35 -----------------------------------------------------------
@@ -211,11 +210,12 @@ function Client:kill()
211 210 end
212 211
213 212 function Client:execute(code, name)
214   - if self:get_player() then
  213 + local playerno = self:get_player()
  214 + if playerno then
215 215 stats.num_exec = stats.num_exec + 1
216   - client_execute(self.fd, code, self.local_output, name)
  216 + player_execute(playerno, self.local_output and self.fd or nil, code, name)
217 217 else
218   - self:writeln("no player to execute the code. sorry")
  218 + self:writeln("you do not have a player. cannot execute your code.")
219 219 end
220 220 end
221 221
@@ -228,9 +228,9 @@ function Client:writeln(line)
228 228 end
229 229
230 230 function Client:rate_limit(action, every)
231   - local time, last = game_time(), self.last_action[action]
232   - if not last or time < last or time > last + every then
233   - self.last_action[action] = game_time()
  231 + local time, last = real_time(), self.last_action[action]
  232 + if not last or time > last + every then
  233 + self.last_action[action] = real_time()
234 234 return true
235 235 else
236 236 self:writeln(string.format("%s too fast. please wait %.1fs...",
@@ -292,22 +292,70 @@ function on_client_close(fd, reason)
292 292 clients[fd] = nil
293 293 end
294 294
295   -function server_new_game()
296   - server_tick = coroutine.wrap(ServerMain)
297   -end
298   -
299   -function server_tick()
300   -end
301   -
302 295 -----------------------------------------------------------
303 296 -- Game C Callbacks
304 297 -----------------------------------------------------------
305 298
306   -function new_game_started()
  299 +function on_game_started()
  300 + -- Demos starten?
307 301 if type(demo) == "string" then
308   - server_start_demo(string.format("%s-%08X.demo", demo, os.time()));
  302 + server_start_writer(string.format("%s-%08X.demo", demo, os.time()), true, true);
309 303 elseif type(demo) == "function" then
310   - server_start_demo(demo())
  304 + server_start_writer(demo(), true, true)
  305 + end
  306 +
  307 + -- Message
  308 + scroller_add("Started map " .. map)
  309 + -- wall("Started map " .. map)
  310 +
  311 + -- server_tick anlegen
  312 + server_tick = coroutine.wrap(ServerMain)
  313 +
  314 + -- Handler fuer Dinge, welche nur beim ersten Spiel aufgerufen werden sollen
  315 + if not first_game then
  316 + first_game = true
  317 +
  318 + -- competition?
  319 + if competition then
  320 + set_realtime(false)
  321 + competition_done_setup = true
  322 + competition_rounds = #maps
  323 + disable_joining = "competition mode"
  324 + for _, code in pairs(competition_bots) do
  325 + appendline(competition_log, string.format("joining '%s' as %d", code, start_bot(code)))
  326 + end
  327 + end
  328 +
  329 + -- Nach dem Starten des ersten Spiels einmalig Funktion autoexec aufrufen
  330 + if autoexec then pcall(autoexec) end
  331 + end
  332 +
  333 + -- Mapchange
  334 + if competition then
  335 + appendline(competition_log, string.format("%d starting on map '%s'", os.time(), map))
  336 + end
  337 +end
  338 +
  339 +function on_game_ended()
  340 + -- competition?
  341 + if competition then
  342 + for pno in each_player() do
  343 + appendline(competition_log, string.format("%d: score %d, creatures %d",
  344 + pno, player_score(pno), player_num_creatures(pno)))
  345 + end
  346 + appendline(competition_log, string.format("%d completed", os.time()))
  347 + competition_rounds = competition_rounds - 1
  348 + if competition_rounds == 0 then
  349 + shutdown()
  350 + end
  351 + end
  352 +
  353 + -- kill all creatures
  354 + killall()
  355 +
  356 + -- reset score
  357 + for pno in each_player() do
  358 + player_set_score(pno, 0)
311 359 end
312 360 end
313 361
@@ -363,7 +411,7 @@ function world_load(map)
363 411 world_make_border = world_make_border;
364 412 world_fill_all = world_fill_all;
365 413 world_tile_center = world_tile_center;
366   - game_info = game_info;
  414 + game_time = game_time;
367 415
368 416 level_spawn_point = world_find_digged_worldcoord;
369 417
@@ -542,6 +590,13 @@ function isnumber(var)
542 590 return tostring(tonumber(var)) == var
543 591 end
544 592
  593 +function appendline(filename, line)
  594 + if not filename then return end
  595 + local file = assert(io.open(filename, "a+"))
  596 + file:write(string.format("%s\n", line))
  597 + file:close()
  598 +end
  599 +
545 600 function kick(fd, msg)
546 601 msg = msg or "kicked"
547 602 clients[fd]:disconnect(msg)
@@ -559,12 +614,6 @@ function killall()
559 614 end
560 615
561 616 function reset()
562   - killall()
563   - for pno in each_player() do
564   - player_set_score(pno, 0)
565   - end
566   - scroller_add("About to restart on map " .. map)
567   - wall("About to restart on map " .. map)
568 617 game_end()
569 618 end
570 619
@@ -603,8 +652,46 @@ function acllist()
603 652 end
604 653 end
605 654
  655 +function start_listener()
  656 + assert(setup_listener(listenaddr, listenport),
  657 + string.format("cannot setup listener on %s:%d", listenaddr, listenport))
  658 +end
  659 +
  660 +function stop_listener()
  661 + setup_listener("", 0)
  662 +end
  663 +
  664 +function start_bot(botcode, logfile, highlevelcode)
  665 + local highlevelcode = highlevelcode or highlevel[1]
  666 + local password = tostring(math.random(100000, 999999))
  667 + local botfile = assert(io.open(botcode, "rb"))
  668 + local botsource = botfile:read("*a")
  669 + botfile:close()
  670 + local playerno = player_create(password, highlevelcode)
  671 + if not playerno then
  672 + error("cannot create new player")
  673 + end
  674 + cprint(string.format("player %d - %s (%s) joined with password '%s'", playerno, name or botcode, botcode, password))
  675 + player_set_no_client_kick_time(playerno, 0)
  676 + local _, _, name = botcode:find("([^/\\]+)\.lua")
  677 + player_set_name(playerno, name or botcode)
  678 + if logfile then
  679 + local ok, logclient = pcall(server_start_writer, logfile, false, false)
  680 + if ok then
  681 + client_attach_to_player(logclient, playerno, password)
  682 + else
  683 + cprint("cannot start log writer: " .. logclient)
  684 + end
  685 + end
  686 + player_execute(playerno, nil, botsource, botcode)
  687 + return playerno
  688 +end
  689 +
606 690 -----------------------------------------------------------
607 691 -- Clienthandler laden
608 692 -----------------------------------------------------------
609 693
610 694 assert(loadfile(PREFIX .. "server.lua"))()
  695 +
  696 +-- setup listen socket
  697 +if listenaddr and listenport then start_listener() end
8 level/cn.lua
@@ -358,19 +358,19 @@ function level_init()
358 358 r = math.random(3),
359 359 a = math.random(100) + 30,
360 360 i = math.random(1000) + 1000,
361   - n = game_info() }
  361 + n = game_time() }
362 362 world_add_food(food_spawner[s].x,
363 363 food_spawner[s].y,
364 364 10000)
365 365 end
366 366
367   - last_food = game_info()
  367 + last_food = game_time()
368 368 end
369 369
370 370 function level_tick()
371   - if game_info() > last_food + 10000 then
  371 + if game_time() > last_food + 10000 then
372 372 for n, spawner in pairs(food_spawner) do
373   - if game_info() > spawner.n then
  373 + if game_time() > spawner.n then
374 374 world_add_food(spawner.x + math.random(spawner.r * 2 + 1) - spawner.r,
375 375 spawner.y + math.random(spawner.r * 2 + 1) - spawner.r,
376 376 spawner.a)
8 level/foo.lua
@@ -1192,19 +1192,19 @@ function level_init()
1192 1192 r = math.random(3),
1193 1193 a = math.random(100) + 30,
1194 1194 i = math.random(1000) + 1000,
1195   - n = game_info() }
  1195 + n = game_time() }
1196 1196 world_add_food(food_spawner[s].x,
1197 1197 food_spawner[s].y,
1198 1198 10000)
1199 1199 end
1200 1200
1201   - last_food = game_info()
  1201 + last_food = game_time()
1202 1202 end
1203 1203
1204 1204 function level_tick()
1205   - if game_info() > last_food + 10000 then
  1205 + if game_time() > last_food + 10000 then
1206 1206 for n, spawner in pairs(food_spawner) do
1207   - if game_info() > spawner.n then
  1207 + if game_time() > spawner.n then
1208 1208 world_add_food(spawner.x + math.random(spawner.r * 2 + 1) - spawner.r,
1209 1209 spawner.y + math.random(spawner.r * 2 + 1) - spawner.r,
1210 1210 spawner.a)
8 level/gpn.lua
@@ -321,19 +321,19 @@ function level_init()
321 321 r = math.random(3),
322 322 a = math.random(100) + 30,
323 323 i = math.random(1000) + 1000,
324   - n = game_info() }
  324 + n = game_time() }
325 325 world_add_food(food_spawner[s].x,
326 326 food_spawner[s].y,
327 327 10000)
328 328 end
329 329
330   - last_food = game_info()
  330 + last_food = game_time()
331 331 end
332 332
333 333 function level_tick()
334   - if game_info() > last_food + 10000 then
  334 + if game_time() > last_food + 10000 then
335 335 for n, spawner in pairs(food_spawner) do
336   - if game_info() > spawner.n then
  336 + if game_time() > spawner.n then
337 337 world_add_food(spawner.x + math.random(spawner.r * 2 + 1) - spawner.r,
338 338 spawner.y + math.random(spawner.r * 2 + 1) - spawner.r,
339 339 spawner.a)
8 level/owl.lua
@@ -69,16 +69,16 @@ function level_init()
69 69 r = math.random(2),
70 70 a = math.random(100) + 30,
71 71 i = math.random(1000) + 1000,
72   - n = game_info() }
  72 + n = game_time() }
73 73 world_add_food(food_spawner[s].x, food_spawner[s].y, 10000)
74 74 end
75   - last_food = game_info()
  75 + last_food = game_time()
76 76 end
77 77
78 78 function level_tick()
79   - if game_info() > last_food + 10000 then
  79 + if game_time() > last_food + 10000 then
80 80 for n, spawner in pairs(food_spawner) do
81   - if game_info() > spawner.n then
  81 + if game_time() > spawner.n then
82 82 world_add_food(spawner.x + math.random(spawner.r * 2 + 1) - spawner.r,
83 83 spawner.y + math.random(spawner.r * 2 + 1) - spawner.r,
84 84 spawner.a)
4 level/water.lua
@@ -2065,12 +2065,12 @@ function level_init()
2065 2065 n = 0,
2066 2066 }
2067 2067 }
2068   - last_food = game_info()
  2068 + last_food = game_time()
2069 2069 end
2070 2070
2071 2071 function level_tick()
2072 2072 for n, spawner in pairs(food_spawner) do
2073   - if game_info() > spawner.n then
  2073 + if game_time() > spawner.n then
2074 2074 world_add_food(spawner.x + math.random(spawner.r * 2 + 1) - spawner.r,
2075 2075 spawner.y + math.random(spawner.r * 2 + 1) - spawner.r,
2076 2076 spawner.a)
48 listener.c
@@ -91,35 +91,31 @@ static void listener_cb(int fd, short event, void *arg) {
91 91 event_add(cb_event, NULL);
92 92 }
93 93
94   -int listener_init() {
  94 +void listener_shutdown() {
  95 + if (listenfd == -1)
  96 + return;
  97 +
  98 + event_del(&listener_event);
  99 + close(listenfd);
  100 + listenfd = -1;
  101 +}
  102 +
  103 +int listener_init(const char *listenaddr, int port) {
95 104 struct sockaddr_in addr;
96 105 static const int one = 1;
97 106
98   - lua_pushliteral(L, "listenport");
99   - lua_rawget(L, LUA_GLOBALSINDEX);
100   -
101   - if (!lua_isnumber(L, -1)) {
102   - fprintf(stderr, "listenport not defined\n");
103   - lua_pop(L, 1);
104   - goto error;
105   - }
106   -
107   - lua_pushliteral(L, "listenaddr");
108   - lua_rawget(L, LUA_GLOBALSINDEX);
  107 + /* Alten Listener, falls vorhanden, schliessen */
  108 + listener_shutdown();
109 109
110   - if (!lua_isstring(L, -1)) {
111   - fprintf(stderr, "listaddr not defined\n");
112   - lua_pop(L, 2);
113   - goto error;
114   - }
  110 + /* Keinen neuen starten? */
  111 + if (strlen(listenaddr) == 0)
  112 + return 1;
115 113
116 114 /* Adressstruktur f�llen */
117 115 memset(&addr, 0, sizeof(struct sockaddr_in));
118 116 addr.sin_family = AF_INET;
119   - addr.sin_addr.s_addr = inet_addr(lua_tostring(L, -1));
120   - addr.sin_port = htons((int)lua_tonumber(L, -2));
121   -
122   - lua_pop(L, 2);
  117 + addr.sin_addr.s_addr = inet_addr(listenaddr);
  118 + addr.sin_port = htons(port);
123 119
124 120 /* Socket erzeugen */
125 121 listenfd = socket(AF_INET, SOCK_STREAM, 0);
@@ -167,15 +163,5 @@ int listener_init() {
167 163 close(listenfd);
168 164 listenfd = -1;
169 165 }
170   - fprintf(stderr, "cannot setup listen socket\n");
171 166 return 0;
172 167 }
173   -
174   -void listener_shutdown() {
175   - if (listenfd != -1) {
176   - event_del(&listener_event);
177   - close(listenfd);
178   - listenfd = -1;
179   - }
180   -}
181   -
2  listener.h
@@ -21,7 +21,7 @@
21 21 #ifndef LISTENER_H
22 22 #define LISTENER_H
23 23
24   -int listener_init();
  24 +int listener_init(const char *addr, int port);
25 25 void listener_shutdown();
26 26
27 27 #endif
116 player.c
@@ -150,7 +150,7 @@ void player_on_all_dead(player_t *player) {
150 150 void player_on_created(player_t *player) {
151 151 // Zeiten zuruecksetzen
152 152 player->all_dead_time = game_time - PLAYER_CREATURE_RESPAWN_DELAY;
153   - player->all_disconnected_time = game_time;
  153 + player->all_disconnected_time = real_time;
154 154 player->spawn_time = game_time;
155 155
156 156 // Event eintragen
@@ -575,11 +575,13 @@ player_t *player_create(const char *pass, const char *highlevel) {
575 575 snprintf(player->name, sizeof(player->name), "player%d", playerno);
576 576 snprintf(player->pass, sizeof(player->pass), "%s", pass);
577 577
578   - player->max_mem = LUA_MAX_MEM;
579   - player->mem_enforce = 0;
580   -
581   - player->max_cycles = LUA_MAX_CPU;
  578 + player->max_mem = LUA_MAX_MEM;
  579 + player->mem_enforce = 0;
582 580
  581 + player->max_cycles = LUA_MAX_CPU;
  582 +
  583 + player->no_client_kick_time = NO_CLIENT_KICK_TIME;
  584 +
583 585 player->L = lua_newstate(player_allocator, player);
584 586 luaL_openlibs(player->L);
585 587
@@ -789,7 +791,7 @@ int player_detach_client(client_t *client, player_t *player) {
789 791 assert(player->num_clients >= 0);
790 792
791 793 if (player->num_clients == 0)
792   - player->all_disconnected_time = game_time;
  794 + player->all_disconnected_time = real_time;
793 795
794 796 client->player = NULL;
795 797
@@ -811,7 +813,7 @@ int player_detach_client(client_t *client, player_t *player) {
811 813 return 1;
812 814 }
813 815
814   -void player_execute_client_lua(client_t *output_client, player_t *player, const char *code, size_t codelen, const char *where) {
  816 +void player_execute_code(player_t *player, client_t *output_client, const char *code, size_t codelen, const char *where) {
815 817 player->output_client = output_client;
816 818 if (luaL_loadbuffer(player->L, code, codelen, where) == 0) {
817 819 player_call_user_lua("during interactive execution", player, 0);
@@ -862,9 +864,9 @@ void player_think() {
862 864 continue;
863 865 }
864 866
865   - // Kein Client mehr da?
866   - if (player->num_clients == 0 &&
867   - player->all_disconnected_time + NO_CLIENT_KICK_TIME < game_time)
  867 + // Kein Client mehr da & soll in diesem Fall gekickt werden?
  868 + if (player->num_clients == 0 && player->no_client_kick_time &&
  869 + player->all_disconnected_time + player->no_client_kick_time < real_time)
868 870 {
869 871 player_destroy(player);
870 872 continue;
@@ -1098,6 +1100,16 @@ static int luaPlayerSetOutputClient(lua_State *L) {
1098 1100 return 1;
1099 1101 }
1100 1102
  1103 +static int luaPlayerSetNoClientKickTime(lua_State *L) {
  1104 + player_get_checked_lua(L, 1)->no_client_kick_time = luaL_checklong(L, 2);
  1105 + return 0;
  1106 +}
  1107 +
  1108 +static int luaPlayerGetNoClientKickTime(lua_State *L) {
  1109 + lua_pushnumber(L, player_get_checked_lua(L, 1)->no_client_kick_time);
  1110 + return 1;
  1111 +}
  1112 +
1101 1113 static int luaPlayerIterator(lua_State *L) {
1102 1114 if (lua_gettop(L) == 0) {
1103 1115 lua_pushcfunction(L, luaPlayerIterator);
@@ -1115,45 +1127,57 @@ static int luaPlayerIterator(lua_State *L) {
1115 1127 return 0;
1116 1128 }
1117 1129
  1130 +static int luaPlayerExecute(lua_State *L) {
  1131 + player_t *player = player_get_checked_lua(L, 1);
  1132 + client_t *client = lua_isnumber(L, 2) ? client_get_checked_lua(L, 2) : NULL;
  1133 + size_t codelen; const char *code = luaL_checklstring(L, 3, &codelen);
  1134 + const char *name = luaL_checkstring(L, 4);
  1135 + player_execute_code(player, client, code, codelen, name);
  1136 + return 0;
  1137 +}
  1138 +
1118 1139 void player_init() {
1119 1140 memset(players, 0, sizeof(players));
1120 1141
1121   - lua_register(L, "player_create", luaPlayerCreate);
1122   - lua_register(L, "player_num_clients", luaPlayerNumClients);
1123   - lua_register(L, "player_num_creatures", luaPlayerNumCreatures);
1124   - lua_register(L, "player_kill", luaPlayerKill);
1125   - lua_register(L, "player_set_color", luaPlayerSetColor);
1126   - lua_register(L, "player_set_name", luaPlayerSetName);
1127   - lua_register(L, "player_get_name", luaPlayerGetName);
1128   - lua_register(L, "player_set_score", luaPlayerSetScore);
1129   - lua_register(L, "player_kill_all_creatures", luaPlayerKillAllCreatures);
1130   - lua_register(L, "player_score", luaPlayerScore);
1131   - lua_register(L, "player_exists", luaPlayerExists);
1132   - lua_register(L, "player_spawntime", luaPlayerSpawnTime);
1133   - lua_register(L, "player_change_score", luaPlayerChangeScore);
1134   - lua_register(L, "player_get_used_mem", luaPlayerGetUsedMem);
1135   - lua_register(L, "player_get_used_cpu", luaPlayerGetCPUUsage);
1136   - lua_register(L, "player_set_output_client", luaPlayerSetOutputClient);
1137   -
1138   - lua_register(L, "each_player", luaPlayerIterator);
1139   -
1140   - lua_register(L, "creature_spawn", luaCreatureSpawn);
1141   - lua_register(L, "creature_get_pos", luaCreatureGetPos);
1142   - lua_register(L, "creature_get_state", luaCreatureGetState);
1143   - lua_register(L, "creature_get_nearest_enemy", luaCreatureGetNearestEnemy);
1144   - lua_register(L, "creature_get_type", luaCreatureGetType);
1145   - lua_register(L, "creature_get_food", luaCreatureGetFood);
1146   - lua_register(L, "creature_get_health", luaCreatureGetHealth);
1147   - lua_register(L, "creature_get_speed", luaCreatureGetSpeed);
1148   - lua_register(L, "creature_get_tile_food", luaCreatureGetTileFood);
1149   - lua_register(L, "creature_get_max_food", luaCreatureGetMaxFood);
1150   - lua_register(L, "creature_get_distance", luaCreatureGetDistance);
1151   - lua_register(L, "creature_get_hitpoints", luaCreatureGetHitpoints);
1152   - lua_register(L, "creature_get_attack_distance", luaCreatureGetAttackDistance);
1153   - lua_register(L, "creature_get_player", luaCreatureGetPlayer);
1154   -
1155   - lua_register(L, "creature_set_food", luaCreatureSetFood);
1156   - lua_register(L, "creature_set_type", luaCreatureSetType);
  1142 + lua_register(L, "player_create", luaPlayerCreate);
  1143 + lua_register(L, "player_num_clients", luaPlayerNumClients);
  1144 + lua_register(L, "player_num_creatures", luaPlayerNumCreatures);
  1145 + lua_register(L, "player_kill", luaPlayerKill);
  1146 + lua_register(L, "player_set_color", luaPlayerSetColor);
  1147 + lua_register(L, "player_set_name", luaPlayerSetName);
  1148 + lua_register(L, "player_get_name", luaPlayerGetName);
  1149 + lua_register(L, "player_set_score", luaPlayerSetScore);
  1150 + lua_register(L, "player_kill_all_creatures", luaPlayerKillAllCreatures);
  1151 + lua_register(L, "player_score", luaPlayerScore);
  1152 + lua_register(L, "player_exists", luaPlayerExists);
  1153 + lua_register(L, "player_spawntime", luaPlayerSpawnTime);
  1154 + lua_register(L, "player_change_score", luaPlayerChangeScore);
  1155 + lua_register(L, "player_get_used_mem", luaPlayerGetUsedMem);
  1156 + lua_register(L, "player_get_used_cpu", luaPlayerGetCPUUsage);
  1157 + lua_register(L, "player_set_output_client", luaPlayerSetOutputClient);
  1158 + lua_register(L, "player_set_no_client_kick_time",luaPlayerSetNoClientKickTime);
  1159 + lua_register(L, "player_get_no_client_kick_time",luaPlayerGetNoClientKickTime);
  1160 + lua_register(L, "player_execute", luaPlayerExecute);
  1161 +
  1162 + lua_register(L, "each_player", luaPlayerIterator);
  1163 +
  1164 + lua_register(L, "creature_spawn", luaCreatureSpawn);
  1165 + lua_register(L, "creature_get_pos", luaCreatureGetPos);
  1166 + lua_register(L, "creature_get_state", luaCreatureGetState);
  1167 + lua_register(L, "creature_get_nearest_enemy", luaCreatureGetNearestEnemy);
  1168 + lua_register(L, "creature_get_type", luaCreatureGetType);
  1169 + lua_register(L, "creature_get_food", luaCreatureGetFood);
  1170 + lua_register(L, "creature_get_health", luaCreatureGetHealth);
  1171 + lua_register(L, "creature_get_speed", luaCreatureGetSpeed);
  1172 + lua_register(L, "creature_get_tile_food", luaCreatureGetTileFood);
  1173 + lua_register(L, "creature_get_max_food", luaCreatureGetMaxFood);
  1174 + lua_register(L, "creature_get_distance", luaCreatureGetDistance);
  1175 + lua_register(L, "creature_get_hitpoints", luaCreatureGetHitpoints);
  1176 + lua_register(L, "creature_get_attack_distance", luaCreatureGetAttackDistance);
  1177 + lua_register(L, "creature_get_player", luaCreatureGetPlayer);
  1178 +
  1179 + lua_register(L, "creature_set_food", luaCreatureSetFood);
  1180 + lua_register(L, "creature_set_type", luaCreatureSetType);
1157 1181
1158 1182 lua_register_constant(L, CREATURE_SMALL);
1159 1183 lua_register_constant(L, CREATURE_BIG);
3  player.h
@@ -49,6 +49,7 @@ typedef struct player_s {
49 49
50 50 int all_dead_time;
51 51 int all_disconnected_time;
  52 + int no_client_kick_time;
52 53
53 54 int max_cycles;
54 55 int cpu_usage;
@@ -81,8 +82,6 @@ void player_on_creature_spawned(player_t *player, struct creature_s *cre
81 82 void player_on_creature_killed(player_t *player, struct creature_s *victim, struct creature_s *killer);
82 83 void player_on_creature_attacked(player_t *player, struct creature_s *victim, struct creature_s *attacker);
83 84
84   -void player_execute_client_lua(client_t *result_client, player_t *player, const char *code, size_t codelen, const char *where);
85   -
86 85 void player_writeto(player_t *player, const void *data, size_t size);
87 86
88 87 void player_set_name(player_t *player, const char *name);
77 server.c
@@ -71,8 +71,8 @@ client_t *server_accept(int fd, const char *address) {
71 71 memset(&clients[fd], 0, sizeof(client_t));
72 72 client_t *client = &clients[fd];
73 73
74   - // Demo Dumper wird leicht unterschiedlich behandelt
75   - client->is_demo_dumper = strstr(address, "special:demodumper") == address;
  74 + // File Writer wird leicht unterschiedlich behandelt
  75 + client->is_file_writer = strstr(address, "special:file") == address;
76 76
77 77 // Non Blocking setzen
78 78 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
@@ -130,7 +130,7 @@ client_t *server_accept(int fd, const char *address) {
130 130 lua_pop(L, 1);
131 131 }
132 132
133   - if (!client->is_demo_dumper)
  133 + if (!client->is_file_writer)
134 134 event_add(&client->rd_event, NULL);
135 135
136 136 return client;
@@ -225,7 +225,7 @@ void server_start_compression(client_t *client) {
225 225
226 226 // Demos sind immer unkomprimiert. Eine Kompression ueber
227 227 // die erstellte Datei macht wesentlich mehr Sinn.
228   - if (client->is_demo_dumper)
  228 + if (client->is_file_writer)
229 229 return;
230 230
231 231 client->strm.zalloc = Z_NULL;
@@ -246,7 +246,7 @@ void server_writeto(client_t *client, const void *data, size_t size) {
246 246 if (size == 0)
247 247 return;
248 248 traffic += size;
249   - if (client->is_demo_dumper) {
  249 + if (client->is_file_writer) {
250 250 write(client_num(client), data, size);
251 251 return;
252 252 }
@@ -314,7 +314,7 @@ void server_destroy(client_t *client, const char *reason) {
314 314 evbuffer_add(client->out_buf, "\r\n", 2);
315 315 }
316 316
317   - if (!client->is_demo_dumper)
  317 + if (!client->is_file_writer)
318 318 evbuffer_write(client->out_buf, fd);
319 319
320 320 evbuffer_free(client->in_buf);
@@ -383,16 +383,13 @@ static void client_turn_into_gui_client(client_t *client) {
383 383 initial_update(client);
384 384 }
385 385
386   -client_t *server_start_demo_writer(const char *demoname, int one_game) {
387   - int server_demo_fd = open(demoname, O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, S_IRUSR|S_IWUSR);
388   - if (server_demo_fd < 0)
  386 +client_t *server_start_file_writer(const char *filename) {
  387 + int fd = open(filename, O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, S_IRUSR|S_IWUSR);
  388 + if (fd < 0)
389 389 return NULL;
390 390 static char address[512];
391   - snprintf(address, sizeof(address), "special:demodumper:%s", demoname);
392   - client_t *demowriter = server_accept(server_demo_fd, address);
393   - client_turn_into_gui_client(demowriter);
394   - demowriter->kick_at_end_of_game = one_game;
395   - return demowriter;
  391 + snprintf(address, sizeof(address), "special:file:%s", filename);
  392 + return server_accept(fd, address);
396 393 }
397 394
398 395 client_t *client_get_checked_lua(lua_State *L, int idx) {
@@ -405,12 +402,18 @@ client_t *client_get_checked_lua(lua_State *L, int idx) {
405 402 return client;
406 403 }
407 404
408   -static int luaStartDemoWriter(lua_State *L) {
409   - const char *demofile = luaL_checkstring(L, 1);
  405 +static int luaStartFileWriter(lua_State *L) {
  406 + const char *file = luaL_checkstring(L, 1);
410 407 int one_game = lua_isboolean(L, 2) ? lua_toboolean(L, 2) : 1;
411   - client_t *demowriter = server_start_demo_writer(demofile, one_game);
412   - if (!demowriter) luaL_error(L, "cannot start demo %s", demofile);
413   - lua_pushnumber(L, client_num(demowriter));
  408 + int is_gui_client = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : 1;
  409 + client_t *filewriter = server_start_file_writer(file);
  410 + if (!filewriter)
  411 + luaL_error(L, "cannot start file %s", file);
  412 + if (is_gui_client)
  413 + client_turn_into_gui_client(filewriter);
  414 + if (one_game)
  415 + filewriter->kick_at_end_of_game = one_game;
  416 + lua_pushnumber(L, client_num(filewriter));
414 417 return 1;
415 418 }
416 419
@@ -446,17 +449,6 @@ static int luaClientIsGuiClient(lua_State *L) {
446 449 return 1;
447 450 }
448 451
449   -static int luaClientExecute(lua_State *L) {
450   - client_t *client = client_get_checked_lua(L, 1);
451   - size_t codelen; const char *code = luaL_checklstring(L, 2, &codelen);
452   - int client_local_output = lua_toboolean(L, 3);
453   - const char *name = luaL_checkstring(L, 4);
454   - if (!client->player)
455   - luaL_error(L, "client %d has no player", client_num(client));
456   - player_execute_client_lua(client_local_output ? client : NULL, client->player, code, codelen, name);
457   - return 0;
458   -}
459   -
460 452 static int luaClientPlayerNumber(lua_State *L) {
461 453 client_t *client = client_get_checked_lua(L, 1);
462 454
@@ -508,6 +500,11 @@ static int luaGetTraffic(lua_State *L) {
508 500 return 1;
509 501 }
510 502
  503 +static int luaSetupListener(lua_State *L) {
  504 + lua_pushboolean(L, listener_init(luaL_checkstring(L, 1), luaL_checklong(L, 2)));
  505 + return 1;
  506 +}
  507 +
511 508 void server_tick() {
512 509 lua_set_cycles(L, 0xFFFFFF);
513 510
@@ -542,36 +539,20 @@ void server_init() {
542 539
543 540 event_init();
544 541
545   - if (!listener_init())
546   - die("error initializing listener");
547   -
548 542 memset(clients, 0, sizeof(clients));
549 543 lua_register(L, "client_write", luaClientWrite);
550 544 lua_register(L, "client_attach_to_player", luaClientAttachToPlayer);
551 545 lua_register(L, "client_detach_from_player",luaClientDetachFromPlayer);
552   - lua_register(L, "client_execute", luaClientExecute);
553 546 lua_register(L, "client_make_guiclient", luaClientMakeGuiClient);
554 547 lua_register(L, "client_is_gui_client", luaClientIsGuiClient);
555 548 lua_register(L, "client_player_number", luaClientPlayerNumber);
556 549 lua_register(L, "client_disconnect", luaClientDisconnect);
557 550 lua_register(L, "client_print", luaClientPrint);
558 551 lua_register(L, "cprint", luaClientPrint);
559   - lua_register(L, "server_start_demo", luaStartDemoWriter);
  552 + lua_register(L, "server_start_writer", luaStartFileWriter);
560 553 lua_register(L, "server_get_traffic", luaGetTraffic);
  554 + lua_register(L, "setup_listener", luaSetupListener);
561 555
562   - // XXX: HACK: stdin client starten
563   -#ifndef NO_CONSOLE_CLIENT
564   - server_accept(STDIN_FILENO, "special:console");
565   -#endif
566   -}
567   -
568   -void server_game_start() {
569   - lua_pushliteral(L, "server_new_game");
570   - lua_rawget(L, LUA_GLOBALSINDEX);
571   - if (lua_pcall(L, 0, 0, 0) != 0) {
572   - fprintf(stderr, "error calling server_new_game: %s\n", lua_tostring(L, -1));
573   - lua_pop(L, 1);
574   - }
575 556 }
576 557
577 558 void server_game_end() {
3  server.h
@@ -47,7 +47,7 @@ typedef struct client_s {
47 47 struct evbuffer *in_buf;
48 48 struct evbuffer *out_buf;
49 49
50   - int is_demo_dumper;
  50 + int is_file_writer;
51 51 int compress;
52 52 z_stream strm;
53 53
@@ -79,7 +79,6 @@ client_t *server_start_demo_writer(const char *demoname, int one_game);
79 79 void server_tick();
80 80
81 81 void server_init();
82   -void server_game_start();
83 82 void server_game_end();
84 83 void server_shutdown();
85 84
19 server.lua
@@ -83,7 +83,10 @@ end
83 83
84 84 function Client:partmenu()
85 85 local playerno = self:get_player()
86   - local warning = player_num_clients(playerno) == 1 and " reattach within 2 minutes or your player will be killed." or ""
  86 + local disconnect_time = player_get_no_client_kick_time(playerno)
  87 + local warning = player_num_clients(playerno) == 1 and disconnect_time ~= 0 and
  88 + string.format(" reattach within %d seconds or your player will be killed.",
  89 + disconnect_time / 1000) or ""
87 90 self:detach()
88 91 self:writeln("detached from player " .. playerno .. "." .. warning)
89 92 end
@@ -133,7 +136,7 @@ function Client:batchmenu()
133 136 else
134 137 code = code .. input .. "\n"
135 138 end
136   - if code:len() > 262144 then
  139 + if #code > 262144 then
137 140 self:writeln("your code is too large.")
138 141 return
139 142 end
@@ -152,7 +155,7 @@ function Client:hexbatchmenu()
152 155 else
153 156 code = code .. input
154 157 end
155   - if code:len() > 262144 then
  158 + if #code > 262144 then
156 159 self:writeln("your code is too large.")
157 160 return
158 161 end
@@ -184,7 +187,7 @@ function Client:highmenu()
184 187 self:writeln("no highlevel api " .. num)
185 188 else
186 189 self.highlevel = api
187   - self:writeln("highlevel api set to '" .. api .. '"')
  190 + self:writeln("highlevel api set to '" .. api .. "'")
188 191 end
189 192 end
190 193
@@ -270,7 +273,7 @@ function Client:info()
270 273 self:writeln("-------------------------------------------------")
271 274 self:writeln("Server Information")
272 275 self:writeln("-------------------+-----------------------------")
273   - self:writeln("uptime | " .. (os.time() - stats.start_time) .. "s")
  276 + self:writeln("uptime | " .. string.format("%ds", real_time() / 1000))
274 277 self:writeln("cpu usage | " .. os.clock() .. "s")
275 278 self:writeln("memory | " .. string.format("%d", collectgarbage("count")) .. "kb")
276 279 self:writeln("traffic | " .. server_get_traffic())
@@ -437,10 +440,10 @@ end
437 440 function ServerMain()
438 441 scroller_add("Welcome to " .. GAME_NAME .. "!")
439 442
440   - local info_time = game_info()
  443 + local info_time = game_time()
441 444 while true do
442   - if game_info() > info_time + 10000 then
443   - info_time = game_info()
  445 + if game_time() > info_time + 10000 then
  446 + info_time = game_time()
444 447 if join_info and join_info ~= "" then
445 448 scroller_add(join_info)
446 449 end

0 comments on commit a8e15a2

Please sign in to comment.
Something went wrong with that request. Please try again.