Update of /cvsroot/once/oncecode/src/server In directory sc8-pr-cvs1:/tmp/cvs-serv28807/src/server Modified Files: ocareastate.cpp ocareastate.h ocmsghandler.h ocplayerstate.cpp ocplayerstate.h ocserver.cpp ocserver.h ocworld.cpp ocworld.h Log Message: - Wouter moved the ocsubscription.cpp and h files from server to common. - ocPlayer and ocArea implement ocSubscribable. - ocPlayerState keeps track by being subscribed. - Added substartmsg, subchangemsg and subendmsg to send to client. - Added newusermsg for client to request new user creation - moved from csHashMap to csSet<T>. - Added csSchedule to ocAreaState, it will keep track of players and entities and call them to update themselves. The world has a Simulate(elapsed_time) method that is called periodically. Players send update messages to the client when they are updated, now every 50 msec. Index: ocareastate.cpp =================================================================== RCS file: /cvsroot/once/oncecode/src/server/ocareastate.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ocareastate.cpp 27 Sep 2003 15:58:41 -0000 1.4 --- ocareastate.cpp 4 Oct 2003 23:54:04 -0000 1.5 *************** *** 20,24 **** --- 20,26 ---- #include "cssysdef.h" #include "ocareastate.h" + #include "csutil/schedule.h" #include "common/ocplayer.h" + #include "ocplayerstate.h" //------------------ ocAreaState ---------------------------- *************** *** 27,30 **** --- 29,34 ---- { next_obj_id=0; + entity_schedule = new csSchedule; + player_schedule = new csSchedule; } *************** *** 33,40 **** --- 37,48 ---- area = id; next_obj_id=0; + entity_schedule = new csSchedule; + player_schedule = new csSchedule; } ocAreaState::~ocAreaState() { + delete entity_schedule; entity_schedule = 0; + delete player_schedule; player_schedule = 0; } *************** *** 88,89 **** --- 96,140 ---- } + void ocAreaState::Simulate(int elapsed) + { + // things in an area happen only based on ticks. + // so only when someones heartbeat happens + // is their update method called (with elapsed time + // since the last call). + player_schedule->TimePassed(elapsed); + entity_schedule->TimePassed(elapsed); + } + + void ocAreaState::AddPlayerOnline(ocID<ocPlayer> player) + { + players_online.Delete(player); + players_online.Push(player); + ocPlayerState* p = player->GetServerState(); + // fixed 50 msec per player + player_schedule->AddRepeatCallback(&SchedPlayer, p, 50); + } + + void ocAreaState::SchedPlayer(void *arg) + { + ocPlayerState *p = (ocPlayerState*)arg; + p->Update(50); + } + + void ocAreaState::RemovePlayerOnline(ocID<ocPlayer> player) + { + players_online.Delete(player); + ocPlayerState* p = player->GetServerState(); + player_schedule->RemoveCallback(p); + } + + void ocAreaState::AddPlayer(ocID<ocPlayer> player) + { + playerlist.Delete(player); + playerlist.Push(player); + } + + void ocAreaState::RemovePlayer(ocID<ocPlayer> player) + { + RemovePlayerOnline(player); + playerlist.Delete(player); + } Index: ocareastate.h =================================================================== RCS file: /cvsroot/once/oncecode/src/server/ocareastate.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ocareastate.h 27 Sep 2003 15:58:41 -0000 1.4 --- ocareastate.h 4 Oct 2003 23:54:05 -0000 1.5 *************** *** 25,28 **** --- 25,29 ---- #include "common/ocentity.h" #include "common/ocserialize.h" + class csSchedule; class ocPlayer; class ocEntity; *************** *** 40,43 **** --- 41,49 ---- /// next object ID to serve as new ID (never 0) uint32 next_obj_id; + + // the schedule of updates for this area + csSchedule *entity_schedule; + // schedule of updates for players online + csSchedule *player_schedule; public: *************** *** 49,52 **** --- 55,71 ---- /// get the players online list for this area csArray< ocID<ocPlayer> >& GetPlayersOnline() {return players_online;} + /// add a player online + void AddPlayerOnline(ocID<ocPlayer> player); + /// remove a player online + void RemovePlayerOnline(ocID<ocPlayer> player); + /// add a player + void AddPlayer(ocID<ocPlayer> player); + /// Remove a player + void RemovePlayer(ocID<ocPlayer> player); + + /// simulate elapsed time in msec (ticks). + void Simulate(int elapsed); + /// run a scheduled player update + static void SchedPlayer(void *arg); /// get a new obj_id in this area Index: ocmsghandler.h =================================================================== RCS file: /cvsroot/once/oncecode/src/server/ocmsghandler.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ocmsghandler.h 5 Sep 2003 10:05:11 -0000 1.4 --- ocmsghandler.h 4 Oct 2003 23:54:05 -0000 1.5 *************** *** 24,32 **** #include "csutil/hashmap.h" #include "common/ocidentifier.h" - - /** - * Added this to shut the compiler up about missing definition of iNetworkConnection - */ - #include "inetwork/driver.h" --- 24,27 ---- Index: ocplayerstate.cpp =================================================================== RCS file: /cvsroot/once/oncecode/src/server/ocplayerstate.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ocplayerstate.cpp 27 Sep 2003 15:58:41 -0000 1.3 --- ocplayerstate.cpp 4 Oct 2003 23:54:05 -0000 1.4 *************** *** 24,27 **** --- 24,31 ---- #include "common/ocplayer.h" #include "common/ocarea.h" + #include "ocserver.h" + #include "common/ocsubstartmsg.h" + #include "common/ocsubchangemsg.h" + #include "common/ocsubendmsg.h" //------------------ ocPlayerState ---------------------------- *************** *** 45,51 **** world->GetPlayersOnline().Delete(player); // make sure in there only once world->GetPlayersOnline().Push(player); ! player->GetCurrentArea()->GetServerState()->GetPlayersOnline(). ! Delete(player); ! player->GetCurrentArea()->GetServerState()->GetPlayersOnline().Push(player); } --- 49,57 ---- world->GetPlayersOnline().Delete(player); // make sure in there only once world->GetPlayersOnline().Push(player); ! player->GetCurrentArea()->GetServerState()->AddPlayerOnline(player); ! ! // subscribe player to 'main' objects: ! player->AddSubscriber(&subscriptionlist); ! player->GetCurrentArea()->AddSubscriber(&subscriptionlist); } *************** *** 54,59 **** netlink = 0; world->GetPlayersOnline().Delete(player); ! player->GetCurrentArea()->GetServerState()->GetPlayersOnline(). ! Delete(player); } --- 60,64 ---- netlink = 0; world->GetPlayersOnline().Delete(player); ! player->GetCurrentArea()->GetServerState()->RemovePlayerOnline(player); } *************** *** 69,73 **** { player.Write(buf); - cn.Write(buf); buf.WriteString(realname); buf.WriteString(email); --- 74,77 ---- *************** *** 78,85 **** { if(!player.Read(buf)) return false; - if(!cn.Read(buf)) return false; if(!buf.ReadString(realname)) return false; if(!buf.ReadString(email)) return false; if(!buf.ReadString(password)) return false; return true; } --- 82,139 ---- { if(!player.Read(buf)) return false; if(!buf.ReadString(realname)) return false; if(!buf.ReadString(email)) return false; if(!buf.ReadString(password)) return false; return true; + } + + /// quick class to store data for callback routines. + class ocPlayerUpdateData { + public: + ocPlayerState *pstate; + csArray<iocSubscribable*> start, change; + }; + + void ocPlayerState::SendPlayerStart(iocSubscribable *able, void* _data) + { + ocPlayerUpdateData* data = (ocPlayerUpdateData*)_data; + data->start.Push(able); + } + + void ocPlayerState::SendPlayerChange(iocSubscribable *able, void* _data) + { + ocPlayerUpdateData* data = (ocPlayerUpdateData*)_data; + data->change.Push(able); + } + + void ocPlayerState::Update(int elapsed) + { + ocServer* server = serversys; // nasty use of global variable. + ocPlayerUpdateData data; + data.pstate = this; + + // send updates to the player + if(subscriptionlist.GetNumStart() > 0) + { + subscriptionlist.LoopSubStartList(SendPlayerStart, &data); + ocSubStartMsg substart; + substart.SetContent(data.start); + server->SendToConnection(&substart, netlink); + } + if(subscriptionlist.GetNumChange() > 0) + { + subscriptionlist.LoopSubChangeList(SendPlayerChange, &data); + ocSubChangeMsg subchange; + subchange.SetContent(data.change); + server->SendToConnection(&subchange, netlink); + } + if(subscriptionlist.GetNumEnd() > 0) + { + ocSubEndMsg subend; + subend.content = subscriptionlist.GetSubEndList(); + server->SendToConnection(&subend, netlink); + } + + // done updates, restart accumulating info + subscriptionlist.Purge(); } Index: ocplayerstate.h =================================================================== RCS file: /cvsroot/once/oncecode/src/server/ocplayerstate.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ocplayerstate.h 27 Sep 2003 15:58:41 -0000 1.4 --- ocplayerstate.h 4 Oct 2003 23:54:05 -0000 1.5 *************** *** 26,31 **** #include "inetwork/driver.h" #include "common/ocserialize.h" ! class ocPlayer; class ocWorld; /** --- 26,33 ---- #include "inetwork/driver.h" #include "common/ocserialize.h" ! #include "common/ocplayer.h" ! #include "common/ocsubscription.h" class ocWorld; + class ocServer; /** *************** *** 36,41 **** /// the player this state belongs to ocID<ocPlayer> player; - /// changenumber - ocChangeNumber cn; /// player info, real name, a place to fill in a long non-nickname. csString realname; --- 38,41 ---- *************** *** 44,51 **** --- 44,60 ---- /// password of player (stored here in plaintext) csString password; + /// list of objects that send notifications of their change here + ocSubscriptionList subscriptionlist; /// network link to player (if online), 0 otherwise csRef<iNetworkConnection> netlink; + /// send subscription start to player + static void SendPlayerStart(iocSubscribable *able, void* _data); + /// send subscription change to player + static void SendPlayerChange(iocSubscribable *able, void* _data); + /// send subscription end to player + void SendPlayerEnd(ocVoidID id); + public: static int ocClassID; *************** *** 66,69 **** --- 75,81 ---- /// logout the player - netlink is zeroed. void Logout(ocWorld* world); + + /// update the player (time has passed, this is player's heartbeat) + void Update(int elapsed_time); //------- iSerial interface ------------------------- Index: ocserver.cpp =================================================================== RCS file: /cvsroot/once/oncecode/src/server/ocserver.cpp,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** ocserver.cpp 27 Sep 2003 15:58:41 -0000 1.14 --- ocserver.cpp 4 Oct 2003 23:54:05 -0000 1.15 *************** *** 24,27 **** --- 24,28 ---- #include "ivaria/reporter.h" #include "iutil/vfs.h" + #include "iutil/virtclk.h" #include "iutil/cfgmgr.h" #include "ivideo/graph2d.h" *************** *** 180,183 **** --- 181,185 ---- } + OC_QUERY_FOR_PLUGIN(vc, iVirtualClock); OC_QUERY_FOR_PLUGIN(cfg, iConfigManager); OC_QUERY_FOR_PLUGIN(vfs, iVFS); *************** *** 295,298 **** --- 297,305 ---- // perform computation to process this frame. HandleIncomingMessages(); + if(world) + { + csTicks elapsed_ticks = vc->GetElapsedTicks(); + world->Simulate(elapsed_ticks); + } if(textonly) csSleep(20); // be friendly to computer *************** *** 406,409 **** --- 413,417 ---- delete oc_global_lookup; oc_global_lookup = 0; concallback = 0; + vc = 0; vfs = 0; cfg = 0; Index: ocserver.h =================================================================== RCS file: /cvsroot/once/oncecode/src/server/ocserver.h,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** ocserver.h 25 Jul 2003 19:57:10 -0000 1.8 --- ocserver.h 4 Oct 2003 23:54:05 -0000 1.9 *************** *** 38,41 **** --- 38,42 ---- class ocPlayer; + struct iVirtualClock; struct iNetworkDriver; struct iNetworkListener; *************** *** 75,78 **** --- 76,80 ---- csRef<iConsoleInput> conin; csRef<iNetworkDriver> netdriver; + csRef<iVirtualClock> vc; /// port on which the server listens Index: ocworld.cpp =================================================================== RCS file: /cvsroot/once/oncecode/src/server/ocworld.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** ocworld.cpp 27 Sep 2003 15:58:41 -0000 1.6 --- ocworld.cpp 4 Oct 2003 23:54:05 -0000 1.7 *************** *** 67,70 **** --- 67,71 ---- int i=playerlist.Push(player); playerlist[i].GetID().SetPtr( &playerlist[i] ); + player.GetCurrentArea()->GetServerState()->AddPlayer(player.GetID()); } *************** *** 140,142 **** --- 141,152 ---- return true; + } + + void ocWorld::Simulate(int elapsedtime) + { + int i; + for(i=0; i<arealist.Length(); i++) + { + arealist[i].GetServerState()->Simulate(elapsedtime); + } } Index: ocworld.h =================================================================== RCS file: /cvsroot/once/oncecode/src/server/ocworld.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ocworld.h 27 Sep 2003 15:58:41 -0000 1.4 --- ocworld.h 4 Oct 2003 23:54:05 -0000 1.5 *************** *** 27,30 **** --- 27,31 ---- class ocPlayer; class ocArea; + class ocServer; /** *************** *** 56,59 **** --- 57,63 ---- virtual bool Deserialize(ocSerialBuffer& buf); virtual int GetSerialType() const {return ocClassID;} + + /// simulate time elapsed in the world, time in msec (ticks). + void Simulate(int elapsed); /// get list of areas |