Permalink
Browse files

* 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...
1 parent 6e63902 commit a8e15a2910ed53c63837dbf0847b67735701344d @dividuum committed Dec 18, 2006
Showing with 335 additions and 219 deletions.
  1. +11 −0 config.lua
  2. +0 −2 creature.c
  3. +0 −1 creature.h
  4. +1 −1 demo2graph.rb
  5. +54 −32 game.c
  6. +9 −3 infond.c
  7. +1 −0 infond.h
  8. +111 −24 infond.lua
  9. +4 −4 level/cn.lua
  10. +4 −4 level/foo.lua
  11. +4 −4 level/gpn.lua
  12. +4 −4 level/owl.lua
  13. +2 −2 level/water.lua
  14. +17 −31 listener.c
  15. +1 −1 listener.h
  16. +70 −46 player.c
  17. +1 −2 player.h
  18. +29 −48 server.c
  19. +1 −2 server.h
  20. +11 −8 server.lua
View
11 config.lua
@@ -49,3 +49,14 @@ banner = [[
~~`---' / |
,-' _/'
]] -- von http://www.asciiworld.com/animals_birds.html
+
+-- competition = true
+-- competition_log = "competition.log"
+-- competition_bots = { "bot1.lua", "bot2.lua" }
+-- time_limit = 10 * 60 * 1000
+-- maps = { "foo", "foo", "foo" }
+-- listenaddr = nil
+
+-- function autoexec()
+-- start_bot("bot1.lua")
+-- end
View
2 creature.c
@@ -1021,9 +1021,7 @@ void creature_init() {
creature_t *creature = &creatures[i];
creature->player = NULL;
}
-}
-void creature_game_start() {
next_free_vm_id = 0;
}
View
1 creature.h
@@ -101,7 +101,6 @@ void creature_send_initial_update(client_t *client);
void creature_to_network(creature_t *creature, int dirtymask, client_t *client);
void creature_init();
-void creature_game_start();
void creature_shutdown();
#endif
View
2 demo2graph.rb
@@ -199,7 +199,7 @@ def dump_world
infon = InfonDemo.new(ARGV[0])
while infon.tick
- #print "%2d:%02d " % [infon.time / 1000 / 60, infon.time / 1000 % 60]
+ print "%2d:%02d " % [infon.time / 1000 / 60, infon.time / 1000 % 60]
#puts "%d %d" % [infon.players.size, infon.creatures.size]
20.times do |i|
if creature = infon.creatures[i]
View
86 game.c
@@ -32,13 +32,14 @@
#include "misc.h"
static int should_end_game = 0;
-static struct timeval start;
+static struct timeval server_start, game_start;
static char intermission[256] = {0};
+static int realtime = 1;
-static int get_tick() {
- static struct timeval now;
+static int get_tick(const struct timeval *ref) {
+ struct timeval now;
gettimeofday(&now , NULL);
- return (now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec - start.tv_usec) / 1000;
+ return (now.tv_sec - ref->tv_sec) * 1000 + (now.tv_usec - ref->tv_usec) / 1000;
}
void game_send_info(client_t *client) {
@@ -84,15 +85,13 @@ static int luaGameEnd(lua_State *L) {
return 0;
}
-static int luaGameInfo(lua_State *L) {
+static int luaGameTime(lua_State *L) {
lua_pushnumber(L, game_time);
- lua_pushnumber(L, world_width());
- lua_pushnumber(L, world_height());
- return 3;
+ return 1;
}
-static int luaGameTime(lua_State *L) {
- lua_pushnumber(L, game_time);
+static int luaRealTime(lua_State *L) {
+ lua_pushnumber(L, real_time);
return 1;
}
@@ -106,6 +105,11 @@ static int luaShutdown(lua_State *L) {
return 0;
}
+static int luaSetRealtime(lua_State *L) {
+ realtime = lua_toboolean(L, 1);
+ return 0;
+}
+
static int luaGameIntermission(lua_State *L) {
snprintf(intermission, sizeof(intermission), "%s", luaL_checkstring(L, 1));
game_send_intermission(SEND_BROADCAST);
@@ -146,76 +150,86 @@ static int luaHexDecode(lua_State *L) {
}
void game_init() {
+ gettimeofday(&server_start, NULL);
+
lua_register(L, "game_end", luaGameEnd);
- lua_register(L, "game_info", luaGameInfo);
lua_register(L, "game_time", luaGameTime);
+ lua_register(L, "real_time", luaRealTime);
lua_register(L, "set_intermission", luaGameIntermission);
lua_register(L, "scroller_add", luaScrollerAdd);
lua_register(L, "hex_decode", luaHexDecode);
+ lua_register(L, "set_realtime", luaSetRealtime);
lua_register(L, "shutdown", luaShutdown);
- lua_pushnumber(L, MAXPLAYERS);
- lua_setglobal(L, "MAXPLAYERS");
-
- lua_pushliteral(L, GAME_NAME);
- lua_setglobal(L, "GAME_NAME");
+ lua_register_constant (L, MAXPLAYERS);
+ lua_register_string_constant(L, GAME_NAME);
}
void game_one_game() {
should_end_game = 0;
game_time = 0;
+ // Zeitinfo an Client
game_send_info(SEND_BROADCAST);
+ // Regeln laden
lua_pushliteral(L, "rules_init");
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_pcall(L, 0, 0, 0) != 0) {
fprintf(stderr, "error calling rules_init: %s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
+ // Karte laden
world_init();
+
+ // Alle Viecher tot. vm_id = 0
creature_init();
// Initialer Worldtick. ruft level_init und ersten level_tick auf.
world_tick();
// Beginn der Zeitrechnung...
int lasttick = 0;
- gettimeofday(&start, NULL);
+ gettimeofday(&game_start, NULL);
- creature_game_start();
- server_game_start();
+ // onPlayerCreated Event an Rules, PLAYER_CREATED an VM
player_game_start();
// Spiel gestartet
- lua_pushliteral(L, "new_game_started");
+ lua_pushliteral(L, "on_game_started");
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_pcall(L, 0, 0, 0) != 0) {
- fprintf(stderr, "error calling new_game_started: %s\n", lua_tostring(L, -1));
+ fprintf(stderr, "error calling on_game_started: %s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
// Rule Handler
game_call_rule_handler("onNewGame", 0);
while (!game_exit && !should_end_game) {
- int tick = get_tick();
- int delta = tick - lasttick;
-
- if (delta < 0 || delta > 200) {
- // Timewarp?
- lasttick = tick;
- continue;
- } else if (delta < 100) {
- usleep(max(95000 - delta * 1000, 1000));
- continue;
+ int tick = get_tick(&game_start);
+ int delta;
+ if (realtime) {
+ delta = tick - lasttick;
+ if (delta < 0 || delta > 200) {
+ // Timewarp?
+ lasttick = tick;
+ continue;
+ } else if (delta < 100) {
+ usleep(max(95000 - delta * 1000, 1000));
+ continue;
+ }
+ } else {
+ delta = 100;
}
-
lasttick = tick;
+
+ // Realtime update
+ real_time = get_tick(&server_start);
// GC
lua_gc(L, LUA_GCSTEP, 1);
@@ -244,6 +258,14 @@ void game_one_game() {
server_tick();
}
+ // Spiel beendet
+ lua_pushliteral(L, "on_game_ended");
+ lua_rawget(L, LUA_GLOBALSINDEX);
+ if (lua_pcall(L, 0, 0, 0) != 0) {
+ fprintf(stderr, "error calling on_game_ended: %s\n", lua_tostring(L, -1));
+ lua_pop(L, 1);
+ }
+
server_game_end();
creature_shutdown();
View
12 infond.c
@@ -45,6 +45,7 @@
lua_State *L;
+int real_time = 0;
int game_time = 0;
int game_paused = 0;
int game_exit = 0;
@@ -71,13 +72,18 @@ int main(int argc, char *argv[]) {
luaL_openlibs(L);
lua_register_string_constant(L, PREFIX);
-
- if (luaL_dofile(L, PREFIX "infond.lua"))
- die("cannot read 'infond.lua': %s", lua_tostring(L, -1));
game_init();
server_init();
player_init();
+
+ if (luaL_dofile(L, PREFIX "infond.lua"))
+ die("cannot execute 'infond.lua': %s", lua_tostring(L, -1));
+
+ // XXX: HACK: stdin client starten
+#ifndef NO_CONSOLE_CLIENT
+ server_accept(STDIN_FILENO, "special:console");
+#endif
#ifdef DAEMONIZING
daemonize(argc, argv);
View
1 infond.h
@@ -25,6 +25,7 @@
extern lua_State *L;
+extern int real_time;
extern int game_time;
extern int game_paused;
extern int game_exit;
View
135 infond.lua
@@ -30,7 +30,6 @@ stats = {
num_players = 0;
num_maps = 0;
num_exec = 0;
- start_time = os.time();
}
-----------------------------------------------------------
@@ -211,11 +210,12 @@ function Client:kill()
end
function Client:execute(code, name)
- if self:get_player() then
+ local playerno = self:get_player()
+ if playerno then
stats.num_exec = stats.num_exec + 1
- client_execute(self.fd, code, self.local_output, name)
+ player_execute(playerno, self.local_output and self.fd or nil, code, name)
else
- self:writeln("no player to execute the code. sorry")
+ self:writeln("you do not have a player. cannot execute your code.")
end
end
@@ -228,9 +228,9 @@ function Client:writeln(line)
end
function Client:rate_limit(action, every)
- local time, last = game_time(), self.last_action[action]
- if not last or time < last or time > last + every then
- self.last_action[action] = game_time()
+ local time, last = real_time(), self.last_action[action]
+ if not last or time > last + every then
+ self.last_action[action] = real_time()
return true
else
self:writeln(string.format("%s too fast. please wait %.1fs...",
@@ -292,22 +292,70 @@ function on_client_close(fd, reason)
clients[fd] = nil
end
-function server_new_game()
- server_tick = coroutine.wrap(ServerMain)
-end
-
-function server_tick()
-end
-
-----------------------------------------------------------
-- Game C Callbacks
-----------------------------------------------------------
-function new_game_started()
+function on_game_started()
+ -- Demos starten?
if type(demo) == "string" then
- server_start_demo(string.format("%s-%08X.demo", demo, os.time()));
+ server_start_writer(string.format("%s-%08X.demo", demo, os.time()), true, true);
elseif type(demo) == "function" then
- server_start_demo(demo())
+ server_start_writer(demo(), true, true)
+ end
+
+ -- Message
+ scroller_add("Started map " .. map)
+ -- wall("Started map " .. map)
+
+ -- server_tick anlegen
+ server_tick = coroutine.wrap(ServerMain)
+
+ -- Handler fuer Dinge, welche nur beim ersten Spiel aufgerufen werden sollen
+ if not first_game then
+ first_game = true
+
+ -- competition?
+ if competition then
+ set_realtime(false)
+ competition_done_setup = true
+ competition_rounds = #maps
+ disable_joining = "competition mode"
+ for _, code in pairs(competition_bots) do
+ appendline(competition_log, string.format("joining '%s' as %d", code, start_bot(code)))
+ end
+ end
+
+ -- Nach dem Starten des ersten Spiels einmalig Funktion autoexec aufrufen
+ if autoexec then pcall(autoexec) end
+ end
+
+ -- Mapchange
+ if competition then
+ appendline(competition_log, string.format("%d starting on map '%s'", os.time(), map))
+ end
+end
+
+function on_game_ended()
+ -- competition?
+ if competition then
+ for pno in each_player() do
+ appendline(competition_log, string.format("%d: score %d, creatures %d",
+ pno, player_score(pno), player_num_creatures(pno)))
+ end
+ appendline(competition_log, string.format("%d completed", os.time()))
+ competition_rounds = competition_rounds - 1
+ if competition_rounds == 0 then
+ shutdown()
+ end
+ end
+
+ -- kill all creatures
+ killall()
+
+ -- reset score
+ for pno in each_player() do
+ player_set_score(pno, 0)
end
end
@@ -363,7 +411,7 @@ function world_load(map)
world_make_border = world_make_border;
world_fill_all = world_fill_all;
world_tile_center = world_tile_center;
- game_info = game_info;
+ game_time = game_time;
level_spawn_point = world_find_digged_worldcoord;
@@ -542,6 +590,13 @@ function isnumber(var)
return tostring(tonumber(var)) == var
end
+function appendline(filename, line)
+ if not filename then return end
+ local file = assert(io.open(filename, "a+"))
+ file:write(string.format("%s\n", line))
+ file:close()
+end
+
function kick(fd, msg)
msg = msg or "kicked"
clients[fd]:disconnect(msg)
@@ -559,12 +614,6 @@ function killall()
end
function reset()
- killall()
- for pno in each_player() do
- player_set_score(pno, 0)
- end
- scroller_add("About to restart on map " .. map)
- wall("About to restart on map " .. map)
game_end()
end
@@ -603,8 +652,46 @@ function acllist()
end
end
+function start_listener()
+ assert(setup_listener(listenaddr, listenport),
+ string.format("cannot setup listener on %s:%d", listenaddr, listenport))
+end
+
+function stop_listener()
+ setup_listener("", 0)
+end
+
+function start_bot(botcode, logfile, highlevelcode)
+ local highlevelcode = highlevelcode or highlevel[1]
+ local password = tostring(math.random(100000, 999999))
+ local botfile = assert(io.open(botcode, "rb"))
+ local botsource = botfile:read("*a")
+ botfile:close()
+ local playerno = player_create(password, highlevelcode)
+ if not playerno then
+ error("cannot create new player")
+ end
+ cprint(string.format("player %d - %s (%s) joined with password '%s'", playerno, name or botcode, botcode, password))
+ player_set_no_client_kick_time(playerno, 0)
+ local _, _, name = botcode:find("([^/\\]+)\.lua")
+ player_set_name(playerno, name or botcode)
+ if logfile then
+ local ok, logclient = pcall(server_start_writer, logfile, false, false)
+ if ok then
+ client_attach_to_player(logclient, playerno, password)
+ else
+ cprint("cannot start log writer: " .. logclient)
+ end
+ end
+ player_execute(playerno, nil, botsource, botcode)
+ return playerno
+end
+
-----------------------------------------------------------
-- Clienthandler laden
-----------------------------------------------------------
assert(loadfile(PREFIX .. "server.lua"))()
+
+-- setup listen socket
+if listenaddr and listenport then start_listener() end
View
8 level/cn.lua
@@ -358,19 +358,19 @@ function level_init()
r = math.random(3),
a = math.random(100) + 30,
i = math.random(1000) + 1000,
- n = game_info() }
+ n = game_time() }
world_add_food(food_spawner[s].x,
food_spawner[s].y,
10000)
end
- last_food = game_info()
+ last_food = game_time()
end
function level_tick()
- if game_info() > last_food + 10000 then
+ if game_time() > last_food + 10000 then
for n, spawner in pairs(food_spawner) do
- if game_info() > spawner.n then
+ if game_time() > spawner.n then
world_add_food(spawner.x + math.random(spawner.r * 2 + 1) - spawner.r,
spawner.y + math.random(spawner.r * 2 + 1) - spawner.r,
spawner.a)
View
8 level/foo.lua
@@ -1192,19 +1192,19 @@ function level_init()
r = math.random(3),
a = math.random(100) + 30,
i = math.random(1000) + 1000,
- n = game_info() }
+ n = game_time() }
world_add_food(food_spawner[s].x,
food_spawner[s].y,
10000)
end
- last_food = game_info()
+ last_food = game_time()
end
function level_tick()
- if game_info() > last_food + 10000 then
+ if game_time() > last_food + 10000 then
for n, spawner in pairs(food_spawner) do
- if game_info() > spawner.n then
+ if game_time() > spawner.n then
world_add_food(spawner.x + math.random(spawner.r * 2 + 1) - spawner.r,
spawner.y + math.random(spawner.r * 2 + 1) - spawner.r,
spawner.a)
View
8 level/gpn.lua
@@ -321,19 +321,19 @@ function level_init()
r = math.random(3),
a = math.random(100) + 30,
i = math.random(1000) + 1000,
- n = game_info() }
+ n = game_time() }
world_add_food(food_spawner[s].x,
food_spawner[s].y,
10000)
end
- last_food = game_info()
+ last_food = game_time()
end
function level_tick()
- if game_info() > last_food + 10000 then
+ if game_time() > last_food + 10000 then
for n, spawner in pairs(food_spawner) do
- if game_info() > spawner.n then
+ if game_time() > spawner.n then
world_add_food(spawner.x + math.random(spawner.r * 2 + 1) - spawner.r,
spawner.y + math.random(spawner.r * 2 + 1) - spawner.r,
spawner.a)
View
8 level/owl.lua
@@ -69,16 +69,16 @@ function level_init()
r = math.random(2),
a = math.random(100) + 30,
i = math.random(1000) + 1000,
- n = game_info() }
+ n = game_time() }
world_add_food(food_spawner[s].x, food_spawner[s].y, 10000)
end
- last_food = game_info()
+ last_food = game_time()
end
function level_tick()
- if game_info() > last_food + 10000 then
+ if game_time() > last_food + 10000 then
for n, spawner in pairs(food_spawner) do
- if game_info() > spawner.n then
+ if game_time() > spawner.n then
world_add_food(spawner.x + math.random(spawner.r * 2 + 1) - spawner.r,
spawner.y + math.random(spawner.r * 2 + 1) - spawner.r,
spawner.a)
View
4 level/water.lua
@@ -2065,12 +2065,12 @@ function level_init()
n = 0,
}
}
- last_food = game_info()
+ last_food = game_time()
end
function level_tick()
for n, spawner in pairs(food_spawner) do
- if game_info() > spawner.n then
+ if game_time() > spawner.n then
world_add_food(spawner.x + math.random(spawner.r * 2 + 1) - spawner.r,
spawner.y + math.random(spawner.r * 2 + 1) - spawner.r,
spawner.a)
View
48 listener.c
@@ -91,35 +91,31 @@ static void listener_cb(int fd, short event, void *arg) {
event_add(cb_event, NULL);
}
-int listener_init() {
+void listener_shutdown() {
+ if (listenfd == -1)
+ return;
+
+ event_del(&listener_event);
+ close(listenfd);
+ listenfd = -1;
+}
+
+int listener_init(const char *listenaddr, int port) {
struct sockaddr_in addr;
static const int one = 1;
- lua_pushliteral(L, "listenport");
- lua_rawget(L, LUA_GLOBALSINDEX);
-
- if (!lua_isnumber(L, -1)) {
- fprintf(stderr, "listenport not defined\n");
- lua_pop(L, 1);
- goto error;
- }
-
- lua_pushliteral(L, "listenaddr");
- lua_rawget(L, LUA_GLOBALSINDEX);
+ /* Alten Listener, falls vorhanden, schliessen */
+ listener_shutdown();
- if (!lua_isstring(L, -1)) {
- fprintf(stderr, "listaddr not defined\n");
- lua_pop(L, 2);
- goto error;
- }
+ /* Keinen neuen starten? */
+ if (strlen(listenaddr) == 0)
+ return 1;
/* Adressstruktur füllen */
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr(lua_tostring(L, -1));
- addr.sin_port = htons((int)lua_tonumber(L, -2));
-
- lua_pop(L, 2);
+ addr.sin_addr.s_addr = inet_addr(listenaddr);
+ addr.sin_port = htons(port);
/* Socket erzeugen */
listenfd = socket(AF_INET, SOCK_STREAM, 0);
@@ -167,15 +163,5 @@ int listener_init() {
close(listenfd);
listenfd = -1;
}
- fprintf(stderr, "cannot setup listen socket\n");
return 0;
}
-
-void listener_shutdown() {
- if (listenfd != -1) {
- event_del(&listener_event);
- close(listenfd);
- listenfd = -1;
- }
-}
-
View
2 listener.h
@@ -21,7 +21,7 @@
#ifndef LISTENER_H
#define LISTENER_H
-int listener_init();
+int listener_init(const char *addr, int port);
void listener_shutdown();
#endif
View
116 player.c
@@ -150,7 +150,7 @@ void player_on_all_dead(player_t *player) {
void player_on_created(player_t *player) {
// Zeiten zuruecksetzen
player->all_dead_time = game_time - PLAYER_CREATURE_RESPAWN_DELAY;
- player->all_disconnected_time = game_time;
+ player->all_disconnected_time = real_time;
player->spawn_time = game_time;
// Event eintragen
@@ -575,11 +575,13 @@ player_t *player_create(const char *pass, const char *highlevel) {
snprintf(player->name, sizeof(player->name), "player%d", playerno);
snprintf(player->pass, sizeof(player->pass), "%s", pass);
- player->max_mem = LUA_MAX_MEM;
- player->mem_enforce = 0;
-
- player->max_cycles = LUA_MAX_CPU;
+ player->max_mem = LUA_MAX_MEM;
+ player->mem_enforce = 0;
+ player->max_cycles = LUA_MAX_CPU;
+
+ player->no_client_kick_time = NO_CLIENT_KICK_TIME;
+
player->L = lua_newstate(player_allocator, player);
luaL_openlibs(player->L);
@@ -789,7 +791,7 @@ int player_detach_client(client_t *client, player_t *player) {
assert(player->num_clients >= 0);
if (player->num_clients == 0)
- player->all_disconnected_time = game_time;
+ player->all_disconnected_time = real_time;
client->player = NULL;
@@ -811,7 +813,7 @@ int player_detach_client(client_t *client, player_t *player) {
return 1;
}
-void player_execute_client_lua(client_t *output_client, player_t *player, const char *code, size_t codelen, const char *where) {
+void player_execute_code(player_t *player, client_t *output_client, const char *code, size_t codelen, const char *where) {
player->output_client = output_client;
if (luaL_loadbuffer(player->L, code, codelen, where) == 0) {
player_call_user_lua("during interactive execution", player, 0);
@@ -862,9 +864,9 @@ void player_think() {
continue;
}
- // Kein Client mehr da?
- if (player->num_clients == 0 &&
- player->all_disconnected_time + NO_CLIENT_KICK_TIME < game_time)
+ // Kein Client mehr da & soll in diesem Fall gekickt werden?
+ if (player->num_clients == 0 && player->no_client_kick_time &&
+ player->all_disconnected_time + player->no_client_kick_time < real_time)
{
player_destroy(player);
continue;
@@ -1098,6 +1100,16 @@ static int luaPlayerSetOutputClient(lua_State *L) {
return 1;
}
+static int luaPlayerSetNoClientKickTime(lua_State *L) {
+ player_get_checked_lua(L, 1)->no_client_kick_time = luaL_checklong(L, 2);
+ return 0;
+}
+
+static int luaPlayerGetNoClientKickTime(lua_State *L) {
+ lua_pushnumber(L, player_get_checked_lua(L, 1)->no_client_kick_time);
+ return 1;
+}
+
static int luaPlayerIterator(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushcfunction(L, luaPlayerIterator);
@@ -1115,45 +1127,57 @@ static int luaPlayerIterator(lua_State *L) {
return 0;
}
+static int luaPlayerExecute(lua_State *L) {
+ player_t *player = player_get_checked_lua(L, 1);
+ client_t *client = lua_isnumber(L, 2) ? client_get_checked_lua(L, 2) : NULL;
+ size_t codelen; const char *code = luaL_checklstring(L, 3, &codelen);
+ const char *name = luaL_checkstring(L, 4);
+ player_execute_code(player, client, code, codelen, name);
+ return 0;
+}
+
void player_init() {
memset(players, 0, sizeof(players));
- lua_register(L, "player_create", luaPlayerCreate);
- lua_register(L, "player_num_clients", luaPlayerNumClients);
- lua_register(L, "player_num_creatures", luaPlayerNumCreatures);
- lua_register(L, "player_kill", luaPlayerKill);
- lua_register(L, "player_set_color", luaPlayerSetColor);
- lua_register(L, "player_set_name", luaPlayerSetName);
- lua_register(L, "player_get_name", luaPlayerGetName);
- lua_register(L, "player_set_score", luaPlayerSetScore);
- lua_register(L, "player_kill_all_creatures", luaPlayerKillAllCreatures);
- lua_register(L, "player_score", luaPlayerScore);
- lua_register(L, "player_exists", luaPlayerExists);
- lua_register(L, "player_spawntime", luaPlayerSpawnTime);
- lua_register(L, "player_change_score", luaPlayerChangeScore);
- lua_register(L, "player_get_used_mem", luaPlayerGetUsedMem);
- lua_register(L, "player_get_used_cpu", luaPlayerGetCPUUsage);
- lua_register(L, "player_set_output_client", luaPlayerSetOutputClient);
-
- lua_register(L, "each_player", luaPlayerIterator);
-
- lua_register(L, "creature_spawn", luaCreatureSpawn);
- lua_register(L, "creature_get_pos", luaCreatureGetPos);
- lua_register(L, "creature_get_state", luaCreatureGetState);
- lua_register(L, "creature_get_nearest_enemy", luaCreatureGetNearestEnemy);
- lua_register(L, "creature_get_type", luaCreatureGetType);
- lua_register(L, "creature_get_food", luaCreatureGetFood);
- lua_register(L, "creature_get_health", luaCreatureGetHealth);
- lua_register(L, "creature_get_speed", luaCreatureGetSpeed);
- lua_register(L, "creature_get_tile_food", luaCreatureGetTileFood);
- lua_register(L, "creature_get_max_food", luaCreatureGetMaxFood);
- lua_register(L, "creature_get_distance", luaCreatureGetDistance);
- lua_register(L, "creature_get_hitpoints", luaCreatureGetHitpoints);
- lua_register(L, "creature_get_attack_distance", luaCreatureGetAttackDistance);
- lua_register(L, "creature_get_player", luaCreatureGetPlayer);
-
- lua_register(L, "creature_set_food", luaCreatureSetFood);
- lua_register(L, "creature_set_type", luaCreatureSetType);
+ lua_register(L, "player_create", luaPlayerCreate);
+ lua_register(L, "player_num_clients", luaPlayerNumClients);
+ lua_register(L, "player_num_creatures", luaPlayerNumCreatures);
+ lua_register(L, "player_kill", luaPlayerKill);
+ lua_register(L, "player_set_color", luaPlayerSetColor);
+ lua_register(L, "player_set_name", luaPlayerSetName);
+ lua_register(L, "player_get_name", luaPlayerGetName);
+ lua_register(L, "player_set_score", luaPlayerSetScore);
+ lua_register(L, "player_kill_all_creatures", luaPlayerKillAllCreatures);
+ lua_register(L, "player_score", luaPlayerScore);
+ lua_register(L, "player_exists", luaPlayerExists);
+ lua_register(L, "player_spawntime", luaPlayerSpawnTime);
+ lua_register(L, "player_change_score", luaPlayerChangeScore);
+ lua_register(L, "player_get_used_mem", luaPlayerGetUsedMem);
+ lua_register(L, "player_get_used_cpu", luaPlayerGetCPUUsage);
+ lua_register(L, "player_set_output_client", luaPlayerSetOutputClient);
+ lua_register(L, "player_set_no_client_kick_time",luaPlayerSetNoClientKickTime);
+ lua_register(L, "player_get_no_client_kick_time",luaPlayerGetNoClientKickTime);
+ lua_register(L, "player_execute", luaPlayerExecute);
+
+ lua_register(L, "each_player", luaPlayerIterator);
+
+ lua_register(L, "creature_spawn", luaCreatureSpawn);
+ lua_register(L, "creature_get_pos", luaCreatureGetPos);
+ lua_register(L, "creature_get_state", luaCreatureGetState);
+ lua_register(L, "creature_get_nearest_enemy", luaCreatureGetNearestEnemy);
+ lua_register(L, "creature_get_type", luaCreatureGetType);
+ lua_register(L, "creature_get_food", luaCreatureGetFood);
+ lua_register(L, "creature_get_health", luaCreatureGetHealth);
+ lua_register(L, "creature_get_speed", luaCreatureGetSpeed);
+ lua_register(L, "creature_get_tile_food", luaCreatureGetTileFood);
+ lua_register(L, "creature_get_max_food", luaCreatureGetMaxFood);
+ lua_register(L, "creature_get_distance", luaCreatureGetDistance);
+ lua_register(L, "creature_get_hitpoints", luaCreatureGetHitpoints);
+ lua_register(L, "creature_get_attack_distance", luaCreatureGetAttackDistance);
+ lua_register(L, "creature_get_player", luaCreatureGetPlayer);
+
+ lua_register(L, "creature_set_food", luaCreatureSetFood);
+ lua_register(L, "creature_set_type", luaCreatureSetType);
lua_register_constant(L, CREATURE_SMALL);
lua_register_constant(L, CREATURE_BIG);
View
3 player.h
@@ -49,6 +49,7 @@ typedef struct player_s {
int all_dead_time;
int all_disconnected_time;
+ int no_client_kick_time;
int max_cycles;
int cpu_usage;
@@ -81,8 +82,6 @@ void player_on_creature_spawned(player_t *player, struct creature_s *cre
void player_on_creature_killed(player_t *player, struct creature_s *victim, struct creature_s *killer);
void player_on_creature_attacked(player_t *player, struct creature_s *victim, struct creature_s *attacker);
-void player_execute_client_lua(client_t *result_client, player_t *player, const char *code, size_t codelen, const char *where);
-
void player_writeto(player_t *player, const void *data, size_t size);
void player_set_name(player_t *player, const char *name);
View
77 server.c
@@ -71,8 +71,8 @@ client_t *server_accept(int fd, const char *address) {
memset(&clients[fd], 0, sizeof(client_t));
client_t *client = &clients[fd];
- // Demo Dumper wird leicht unterschiedlich behandelt
- client->is_demo_dumper = strstr(address, "special:demodumper") == address;
+ // File Writer wird leicht unterschiedlich behandelt
+ client->is_file_writer = strstr(address, "special:file") == address;
// Non Blocking setzen
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
@@ -130,7 +130,7 @@ client_t *server_accept(int fd, const char *address) {
lua_pop(L, 1);
}
- if (!client->is_demo_dumper)
+ if (!client->is_file_writer)
event_add(&client->rd_event, NULL);
return client;
@@ -225,7 +225,7 @@ void server_start_compression(client_t *client) {
// Demos sind immer unkomprimiert. Eine Kompression ueber
// die erstellte Datei macht wesentlich mehr Sinn.
- if (client->is_demo_dumper)
+ if (client->is_file_writer)
return;
client->strm.zalloc = Z_NULL;
@@ -246,7 +246,7 @@ void server_writeto(client_t *client, const void *data, size_t size) {
if (size == 0)
return;
traffic += size;
- if (client->is_demo_dumper) {
+ if (client->is_file_writer) {
write(client_num(client), data, size);
return;
}
@@ -314,7 +314,7 @@ void server_destroy(client_t *client, const char *reason) {
evbuffer_add(client->out_buf, "\r\n", 2);
}
- if (!client->is_demo_dumper)
+ if (!client->is_file_writer)
evbuffer_write(client->out_buf, fd);
evbuffer_free(client->in_buf);
@@ -383,16 +383,13 @@ static void client_turn_into_gui_client(client_t *client) {
initial_update(client);
}
-client_t *server_start_demo_writer(const char *demoname, int one_game) {
- int server_demo_fd = open(demoname, O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, S_IRUSR|S_IWUSR);
- if (server_demo_fd < 0)
+client_t *server_start_file_writer(const char *filename) {
+ int fd = open(filename, O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, S_IRUSR|S_IWUSR);
+ if (fd < 0)
return NULL;
static char address[512];
- snprintf(address, sizeof(address), "special:demodumper:%s", demoname);
- client_t *demowriter = server_accept(server_demo_fd, address);
- client_turn_into_gui_client(demowriter);
- demowriter->kick_at_end_of_game = one_game;
- return demowriter;
+ snprintf(address, sizeof(address), "special:file:%s", filename);
+ return server_accept(fd, address);
}
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) {
return client;
}
-static int luaStartDemoWriter(lua_State *L) {
- const char *demofile = luaL_checkstring(L, 1);
+static int luaStartFileWriter(lua_State *L) {
+ const char *file = luaL_checkstring(L, 1);
int one_game = lua_isboolean(L, 2) ? lua_toboolean(L, 2) : 1;
- client_t *demowriter = server_start_demo_writer(demofile, one_game);
- if (!demowriter) luaL_error(L, "cannot start demo %s", demofile);
- lua_pushnumber(L, client_num(demowriter));
+ int is_gui_client = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : 1;
+ client_t *filewriter = server_start_file_writer(file);
+ if (!filewriter)
+ luaL_error(L, "cannot start file %s", file);
+ if (is_gui_client)
+ client_turn_into_gui_client(filewriter);
+ if (one_game)
+ filewriter->kick_at_end_of_game = one_game;
+ lua_pushnumber(L, client_num(filewriter));
return 1;
}
@@ -446,17 +449,6 @@ static int luaClientIsGuiClient(lua_State *L) {
return 1;
}
-static int luaClientExecute(lua_State *L) {
- client_t *client = client_get_checked_lua(L, 1);
- size_t codelen; const char *code = luaL_checklstring(L, 2, &codelen);
- int client_local_output = lua_toboolean(L, 3);
- const char *name = luaL_checkstring(L, 4);
- if (!client->player)
- luaL_error(L, "client %d has no player", client_num(client));
- player_execute_client_lua(client_local_output ? client : NULL, client->player, code, codelen, name);
- return 0;
-}
-
static int luaClientPlayerNumber(lua_State *L) {
client_t *client = client_get_checked_lua(L, 1);
@@ -508,6 +500,11 @@ static int luaGetTraffic(lua_State *L) {
return 1;
}
+static int luaSetupListener(lua_State *L) {
+ lua_pushboolean(L, listener_init(luaL_checkstring(L, 1), luaL_checklong(L, 2)));
+ return 1;
+}
+
void server_tick() {
lua_set_cycles(L, 0xFFFFFF);
@@ -542,36 +539,20 @@ void server_init() {
event_init();
- if (!listener_init())
- die("error initializing listener");
-
memset(clients, 0, sizeof(clients));
lua_register(L, "client_write", luaClientWrite);
lua_register(L, "client_attach_to_player", luaClientAttachToPlayer);
lua_register(L, "client_detach_from_player",luaClientDetachFromPlayer);
- lua_register(L, "client_execute", luaClientExecute);
lua_register(L, "client_make_guiclient", luaClientMakeGuiClient);
lua_register(L, "client_is_gui_client", luaClientIsGuiClient);
lua_register(L, "client_player_number", luaClientPlayerNumber);
lua_register(L, "client_disconnect", luaClientDisconnect);
lua_register(L, "client_print", luaClientPrint);
lua_register(L, "cprint", luaClientPrint);
- lua_register(L, "server_start_demo", luaStartDemoWriter);
+ lua_register(L, "server_start_writer", luaStartFileWriter);
lua_register(L, "server_get_traffic", luaGetTraffic);
+ lua_register(L, "setup_listener", luaSetupListener);
- // XXX: HACK: stdin client starten
-#ifndef NO_CONSOLE_CLIENT
- server_accept(STDIN_FILENO, "special:console");
-#endif
-}
-
-void server_game_start() {
- lua_pushliteral(L, "server_new_game");
- lua_rawget(L, LUA_GLOBALSINDEX);
- if (lua_pcall(L, 0, 0, 0) != 0) {
- fprintf(stderr, "error calling server_new_game: %s\n", lua_tostring(L, -1));
- lua_pop(L, 1);
- }
}
void server_game_end() {
View
3 server.h
@@ -47,7 +47,7 @@ typedef struct client_s {
struct evbuffer *in_buf;
struct evbuffer *out_buf;
- int is_demo_dumper;
+ int is_file_writer;
int compress;
z_stream strm;
@@ -79,7 +79,6 @@ client_t *server_start_demo_writer(const char *demoname, int one_game);
void server_tick();
void server_init();
-void server_game_start();
void server_game_end();
void server_shutdown();
View
19 server.lua
@@ -83,7 +83,10 @@ end
function Client:partmenu()
local playerno = self:get_player()
- local warning = player_num_clients(playerno) == 1 and " reattach within 2 minutes or your player will be killed." or ""
+ local disconnect_time = player_get_no_client_kick_time(playerno)
+ local warning = player_num_clients(playerno) == 1 and disconnect_time ~= 0 and
+ string.format(" reattach within %d seconds or your player will be killed.",
+ disconnect_time / 1000) or ""
self:detach()
self:writeln("detached from player " .. playerno .. "." .. warning)
end
@@ -133,7 +136,7 @@ function Client:batchmenu()
else
code = code .. input .. "\n"
end
- if code:len() > 262144 then
+ if #code > 262144 then
self:writeln("your code is too large.")
return
end
@@ -152,7 +155,7 @@ function Client:hexbatchmenu()
else
code = code .. input
end
- if code:len() > 262144 then
+ if #code > 262144 then
self:writeln("your code is too large.")
return
end
@@ -184,7 +187,7 @@ function Client:highmenu()
self:writeln("no highlevel api " .. num)
else
self.highlevel = api
- self:writeln("highlevel api set to '" .. api .. '"')
+ self:writeln("highlevel api set to '" .. api .. "'")
end
end
@@ -270,7 +273,7 @@ function Client:info()
self:writeln("-------------------------------------------------")
self:writeln("Server Information")
self:writeln("-------------------+-----------------------------")
- self:writeln("uptime | " .. (os.time() - stats.start_time) .. "s")
+ self:writeln("uptime | " .. string.format("%ds", real_time() / 1000))
self:writeln("cpu usage | " .. os.clock() .. "s")
self:writeln("memory | " .. string.format("%d", collectgarbage("count")) .. "kb")
self:writeln("traffic | " .. server_get_traffic())
@@ -437,10 +440,10 @@ end
function ServerMain()
scroller_add("Welcome to " .. GAME_NAME .. "!")
- local info_time = game_info()
+ local info_time = game_time()
while true do
- if game_info() > info_time + 10000 then
- info_time = game_info()
+ if game_time() > info_time + 10000 then
+ info_time = game_time()
if join_info and join_info ~= "" then
scroller_add(join_info)
end

0 comments on commit a8e15a2

Please sign in to comment.