ADDED src/ServerEntity.h Index: src/ServerEntity.h ================================================================== --- /dev/null +++ src/ServerEntity.h @@ -0,0 +1,9 @@ +#import <ObjFW/ObjFW.h> + +// server side version of "entity" type +@interface ServerEntity: OFObject +@property (nonatomic) bool spawned; +@property (nonatomic) int spawnsecs; + ++ (instancetype)entity; +@end ADDED src/ServerEntity.m Index: src/ServerEntity.m ================================================================== --- /dev/null +++ src/ServerEntity.m @@ -0,0 +1,8 @@ +#import "ServerEntity.h" + +@implementation ServerEntity ++ (instancetype)entity +{ + return [[self alloc] init]; +} +@end Index: src/meson.build ================================================================== --- src/meson.build +++ src/meson.build @@ -16,10 +16,11 @@ 'OFString+Cube.mm', 'PersistentEntity.m', 'Projectile.m', 'ResolverResult.mm', 'ResolverThread.mm', + 'ServerEntity.m', 'ServerInfo.mm', 'Variable.mm', 'clients.mm', 'clientextras.mm', 'clientgame.mm', @@ -67,10 +68,11 @@ win_subsystem: 'windows') executable('server', [ 'Client.mm', + 'ServerEntity.m', 'server.mm', 'serverms.mm', 'serverutil.mm', 'tools.mm', ], Index: src/server.mm ================================================================== --- src/server.mm +++ src/server.mm @@ -3,39 +3,34 @@ #include "cube.h" #import "Client.h" #import "Entity.h" +#import "ServerEntity.h" enum { ST_EMPTY, ST_LOCAL, ST_TCPIP }; static OFMutableArray<Client *> *clients; int maxclients = 8; static OFString *smapname; -// server side version of "entity" type -struct server_entity { - bool spawned; - int spawnsecs; -}; - -vector<server_entity> sents; +static OFMutableArray<ServerEntity *> *sents; // true when map has changed and waiting for clients to send item bool notgotitems = true; int mode = 0; // hack: called from savegame code, only works in SP void restoreserverstate(OFArray<Entity *> *ents) { - loopv(sents) - { - sents[i].spawned = ents[i].spawned; - sents[i].spawnsecs = 0; - } + [sents enumerateObjectsUsingBlock:^( + ServerEntity *e, size_t i, bool *stop) { + e.spawned = ents[i].spawned; + e.spawnsecs = 0; + }]; } int interm = 0, minremain = 0, mapend = 0; bool mapreload = false; @@ -114,19 +109,19 @@ } void resetitems() { - sents.setsize(0); + [sents removeAllObjects]; notgotitems = true; } void pickup(uint i, int sec, int sender) // server side item pickup, acknowledge // first client that gets it { - if (i >= (uint)sents.length()) + if (i >= (uint)sents.count) return; if (sents[i].spawned) { sents[i].spawned = false; sents[i].spawnsecs = sec; send2(true, sender, SV_ITEMACC, i); @@ -228,13 +223,13 @@ case SV_ITEMLIST: { int n; while ((n = getint(p)) != -1) if (notgotitems) { - server_entity se = { false, 0 }; - while (sents.length() <= n) - sents.add(se); + while (sents.count <= n) + [sents addObject:[ServerEntity + entity]]; sents[n].spawned = true; } notgotitems = false; break; } @@ -302,11 +297,11 @@ send_welcome(int n) { ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE); uchar *start = packet->data; - uchar *p = start + 2; + __block uchar *p = start + 2; putint(p, SV_INITS2C); putint(p, n); putint(p, PROTOCOL_VERSION); putint(p, *smapname.UTF8String); sendstring(serverpassword, p); @@ -314,11 +309,15 @@ if (smapname.length > 0) { putint(p, SV_MAPCHANGE); sendstring(smapname, p); putint(p, mode); putint(p, SV_ITEMLIST); - loopv(sents) if (sents[i].spawned) putint(p, i); + [sents enumerateObjectsUsingBlock:^( + ServerEntity *e, size_t i, bool *stop) { + if (e.spawned) + putint(p, i); + }]; putint(p, -1); } *(ushort *)start = ENET_HOST_TO_NET_16(p - start); enet_packet_resize(packet, p - start); send(n, packet); @@ -400,19 +399,19 @@ void serverslice(int seconds, unsigned int timeout) // main server update, called from cube main loop in // sp, or dedicated server loop { - loopv(sents) // spawn entities when timer reached - { - if (sents[i].spawnsecs && - (sents[i].spawnsecs -= seconds - lastsec) <= 0) { - sents[i].spawnsecs = 0; - sents[i].spawned = true; + // spawn entities when timer reached + [sents enumerateObjectsUsingBlock:^( + ServerEntity *e, size_t i, bool *stop) { + if (e.spawnsecs && (e.spawnsecs -= seconds - lastsec) <= 0) { + e.spawnsecs = 0; + e.spawned = true; send2(true, -1, SV_ITEMSPAWN, i); } - } + }]; lastsec = seconds; if ((mode > 1 || (mode == 0 && nonlocalclients)) && seconds > mapend - minremain * 60) @@ -532,10 +531,11 @@ initserver(bool dedicated, int uprate, OFString *sdesc, OFString *ip, OFString *master, OFString *passwd, int maxcl) { serverpassword = passwd; maxclients = maxcl; + sents = [[OFMutableArray alloc] init]; servermsinit(master ? master : @"wouter.fov120.com/cube/masterserver/", sdesc, dedicated); if ((isdedicated = dedicated)) { ENetAddress address = { ENET_HOST_ANY, CUBE_SERVER_PORT };