oolite-multiplayer
Moderators: winston, another_commander
Server Code
I have found this objective-c code for a game server.
I would be happy to help with the server code
Pete
I would be happy to help with the server code
Pete
Code: Select all
#include <Foundation/Foundation.h>
#include "GameServer.h"
#include "GameClient.h"
#import <stdint.h>
#import <winsock2.h>
/*
* GameServer class declaration:
* Adopt the GameServer protocol and declare
* GameServer instance variables.
*/
@interface GameServer : NSObject <GameServer>
{
NSMutableDictionary *delayUntil; // Delays to re-joining GameServer.
NSMutableDictionary *currentPlayers; // Proxies to each client.
NSMutableDictionary *hasWon; // Success in game for each player.
}
@end
/*
* GameServer class implementation.
*/
@implementation GameServer
/* Initialise GameServer's instance variables. */
- (id) init
{
NSLog (@"Run.");
self = [super init];
if (self != nil)
{
/*
* Create a dictionary for a maximum of
* 10 named players that will hold a
* re-joining time delay.
*/
delayUntil = [[NSMutableDictionary alloc]
initWithCapacity: 10];
/*
* Create a dictionary that will hold the
* names of these players and a proxy for
* the received client objects.
*/
currentPlayers = [[NSMutableDictionary alloc]
initWithCapacity: 10];
/*
* Create a dictionary that will record
* a win for any of these named players.
*/
hasWon = [[NSMutableDictionary alloc]
initWithCapacity: 10];
}
return self;
}
/* Release GameServer's instance variables. */
- (void) dealloc
{
RELEASE(delayUntil);
RELEASE(currentPlayers);
RELEASE(hasWon);
[super dealloc];
}
/*
* Implement mayJoin:: as declared in the protocol.
* Adds the client to the list of current players.
* Each player is represented at the server by both
* name and by proxy to the received client object.
* A player cannot join the game if they are already playing,
* or if joining has been delayed until a later date.
*/
- (BOOL) mayJoin: (id)client asPlayer: (NSString*)name
{
NSDate *delay; // The time a player can re-join the game.
NSString *aMessage;
if (name == nil)
{
NSLog(@"Attempt to join nil user");
return NO;
}
/* Has the player already joined the game? */
if ([currentPlayers objectForKey: name] != nil)
{
/* Inform the client that they cannot join. */
aMessage = @"\nSorry, but you are already playing GameServer!\n";
[client clientMessage: aMessage];
return NO;
}
/* Get the player's time delay for re-joining. */
delay = [delayUntil objectForKey: name];
/*
* Can the player join the game? Yes if there is
* no restriction or if the time delay has passed;
* otherwise no, they cannot join.
*/
if (delay == nil || [delay timeIntervalSinceNow] <= 0.0)
{
/* Remove the old restriction on re-joining the game. */
[delayUntil removeObjectForKey: name];
/* Add the player to the list of current players. */
[currentPlayers setObject: client forKey: name];
[hasWon setObject: @"NO" forKey: name]; // They've not won yet.
/* Inform the client that they have joined the game. */
aMessage = @"\nWelcome to GameServer\n";
[client clientMessage: aMessage];
return YES;
}
else
{
/* Inform the client that they cannot re-join. */
aMessage = @"\nSorry, you cannot re-join GameServer yet.\n";
[client clientMessage: aMessage];
return NO;
}
}
/*
* Implement startGame: as declared in the protocol.
* Simply ask the player if they want to win, and get
* there reply.
*/
- (int) startGame: (NSString *)name
{
NSString *aMessage;
id client;
int reply;
client = [currentPlayers objectForKey: name];
aMessage = @"\nDo you want to win this game? (Y/N ) ... ";
[client clientMessage: aMessage];
reply = [client clientReply];
if (reply == 'y' || reply == 'Y')
[hasWon setObject: @"YES" forKey: name]; // They win.
else [hasWon setObject: @"NO" forKey: name]; // They loose.
return 0;
}
/*
* Implement endGame: as declared in the protocol.
* Removes a player from the game, and either sets
* a restriction on the player re-joining or removes
* the current restriction.
*/
- (BOOL) endGame: (NSString*)name
{
id client;
NSString *aMessage, *yesOrNo;
NSDate *now, *delay;
NSTimeInterval twoHours = 2 * 60 * 60; // Seconds in 2 hours.
if (name == nil)
{
NSLog(@"Attempt to end nil user");
return NO;
}
now = [NSDate date];
delay = [now addTimeInterval: twoHours];
client = [currentPlayers objectForKey: name];
yesOrNo = [hasWon objectForKey: name];
if ([yesOrNo isEqualToString: @"YES"]) // Has player won?
{
/*
* Player wins, no time delay to re-joining the game.
* Remove any re-joining restriction and send
* a message to the client.
*/
[delayUntil removeObjectForKey: name];
aMessage = @"\nWell played: you can re-join GameServer at any time.\n";
[client clientMessage: aMessage];
}
else // Player lost
{
/*
* Set a time delay for re-joining the game,
* and send a message to the client.
*/
[delayUntil setObject: delay forKey: name];
aMessage = @"\nYou lost, but you can re-join GameServer in 2 hours.\n";
[client clientMessage: aMessage];
}
/* Remove the player from the current game. */
[currentPlayers removeObjectForKey: name];
[hasWon removeObjectForKey: name];
return YES;
}
@end // End of GameServer class implementation
/*
* The main function of the server program simply
* vends the root object and starts the runloop.
*/
int main(int argc, char** argv)
{
CREATE_AUTORELEASE_POOL(pool);
NSLog (@"Starting Oolite Server");
GameServer *server = AUTORELEASE([GameServer new]);
NSSocketPort *port = [NSSocketPort port];
NSConnection *connXion = [NSConnection connectionWithReceivePort: port sendPort: port];
[connXion setRootObject: server];
NSLog (@"2");
[NSSocketPortNameServer sharedInstance];
[connXion registerName:@"Oolite" withNameServer: [NSSocketPortNameServer sharedInstance]];
[[NSRunLoop currentRunLoop] run];
RELEASE(pool);
return 0;
}
Last edited by Pete_72 on Mon Sep 22, 2008 7:52 pm, edited 1 time in total.
- DaddyHoggy
- Intergalactic Spam Assassin
- Posts: 8515
- Joined: Tue Dec 05, 2006 9:43 pm
- Location: Newbury, UK
- Contact:
Welcome Pete - that's a lot of code for a first post!
EDIT: Code deleted as its been tagged in post above
Has anybody actually got any thoughts on how precisely this "multi-player" version might work - In my mind the simplest method would be to make it an arena type format - everybody turns up at a particular system - fights - winner perhaps gets something (or nothing) that he can take back into the main game (credits?).
EDIT: Code deleted as its been tagged in post above
Has anybody actually got any thoughts on how precisely this "multi-player" version might work - In my mind the simplest method would be to make it an arena type format - everybody turns up at a particular system - fights - winner perhaps gets something (or nothing) that he can take back into the main game (credits?).
Last edited by DaddyHoggy on Tue Sep 23, 2008 1:26 pm, edited 1 time in total.
Oolite Life is now revealed hereSelezen wrote:Apparently I was having a DaddyHoggy moment.
One Planet One Server
I think the best way is that the different planet are controlled by one server program. (Maybe on the same server)
When you Witch drive to a different planet the you log onto to a new server entity. (without realising)
This way the information you need is x,y,z coordiantes and angles, energy level, ship type.
When your ship is destoryed by another ship the cargo will be lauched into space and others can pick up.
To keep it simple people can load their saved games and will log onto the server as player 1-64.
The Oolite Client will generator the ships from the server coordinates
Pete
When you Witch drive to a different planet the you log onto to a new server entity. (without realising)
This way the information you need is x,y,z coordiantes and angles, energy level, ship type.
When your ship is destoryed by another ship the cargo will be lauched into space and others can pick up.
To keep it simple people can load their saved games and will log onto the server as player 1-64.
The Oolite Client will generator the ships from the server coordinates
Pete
Has anyone ever played Vendetta Online? It's essentially Elite-like gameplay in a multiplayer setting. I did a little bit of beta-testing a few years ago, but ran out of time, and have never played the commercial release.
If you think the current AI pirates are jerks, just try a trade run through systems full of actual human players who have all the cool toys, and only play to blow up newbies....
If you think the current AI pirates are jerks, just try a trade run through systems full of actual human players who have all the cool toys, and only play to blow up newbies....
Well I have put some thought into it and I have a few questions to see if this approach is feasible.
I am thinking about 1 Master server that does the heavy non time critical network stuff with TCP.
Like login, player storage in a database, keeping track of planets and such.
1-several slave servers that run on decentralized systems and register with the master server. The master server asks the least busy slave server to create a planet server.
These planet servers are the real processes that create one planet and update the ships in that planet system.
This traffic would be with UDP.
A client would login to the master server and request a planet jump.
The master server will lookup in its table if such a planet already exists on one of the slave server systems.
If not it will request the creation on the least busy slave server.
The client will get the IP and port of that planet server and connect via UDP.
To get as many players on one planet server it needs to send as little UDP traffic as possible.
My idea for that would be to use a sort of acknowledges in the UDP traffic.
Something like this:
The client connects to the planet.
It gets a initial state of the planet everything within a 2 radar distance of the starting point.
The planet server keeps track of the last 100 states (25 states per second for 4 seconds).
The planet server sends out any changes to the state for each client.
In many cases there would be no changes (asteroids to not change course of speed etc.)
The client sends its own changes to the planet server and also sends back a state number that was the last good and acknowledged state.
The planet server will use that last ACK'ed state and calculate the difference to the current state and send it back, plus the current state number.
The client will update the state and also use the state number in the next transmission.
If one client did not send anything (no use changes to the ship) for more than 1 second it will send a NULL packet and receive an updated state number.
More than 4 seconds of no update would need a reinitialization of the state on the client.
Guess that is a lot to digest at first, but I hope that the design would work.
What I am not sure of is the 100 states that needs to be implemented on the client and on the server.
Plus the differences to a given state calculated.
How much data would be needed for this? Say for a max of 16 players in a 2 radar distance.
Any ideas and/or better ideas are welcome.
Cheers,
CarsteN
I am thinking about 1 Master server that does the heavy non time critical network stuff with TCP.
Like login, player storage in a database, keeping track of planets and such.
1-several slave servers that run on decentralized systems and register with the master server. The master server asks the least busy slave server to create a planet server.
These planet servers are the real processes that create one planet and update the ships in that planet system.
This traffic would be with UDP.
A client would login to the master server and request a planet jump.
The master server will lookup in its table if such a planet already exists on one of the slave server systems.
If not it will request the creation on the least busy slave server.
The client will get the IP and port of that planet server and connect via UDP.
To get as many players on one planet server it needs to send as little UDP traffic as possible.
My idea for that would be to use a sort of acknowledges in the UDP traffic.
Something like this:
The client connects to the planet.
It gets a initial state of the planet everything within a 2 radar distance of the starting point.
The planet server keeps track of the last 100 states (25 states per second for 4 seconds).
The planet server sends out any changes to the state for each client.
In many cases there would be no changes (asteroids to not change course of speed etc.)
The client sends its own changes to the planet server and also sends back a state number that was the last good and acknowledged state.
The planet server will use that last ACK'ed state and calculate the difference to the current state and send it back, plus the current state number.
The client will update the state and also use the state number in the next transmission.
If one client did not send anything (no use changes to the ship) for more than 1 second it will send a NULL packet and receive an updated state number.
More than 4 seconds of no update would need a reinitialization of the state on the client.
Guess that is a lot to digest at first, but I hope that the design would work.
What I am not sure of is the 100 states that needs to be implemented on the client and on the server.
Plus the differences to a given state calculated.
How much data would be needed for this? Say for a max of 16 players in a 2 radar distance.
Any ideas and/or better ideas are welcome.
Cheers,
CarsteN
- DaddyHoggy
- Intergalactic Spam Assassin
- Posts: 8515
- Joined: Tue Dec 05, 2006 9:43 pm
- Location: Newbury, UK
- Contact:
What level of fidelity are you expecting to achieve with 25 updates per second? Important if you're trying to shoot the weapon pod sub entities off another ship.
For example using the IEEE 1278 Standard DIS it *recommends* a new state PDU is issued every 1m or 3º of movement (in any plane), plus everytime a visual change occurs (which in the real world for an aircraft - the nearest spaceship equivalent would be flaps/control surfaces up/down, nav lights on/off, thrust changes, weapons fired)
In a modern combat sim networked to another in a dog fight situation emits about 200 entity state data units a second and we often run at higher than that if we want very accurate/smooth positional data (i.e. above the minimum recommended)
For example using the IEEE 1278 Standard DIS it *recommends* a new state PDU is issued every 1m or 3º of movement (in any plane), plus everytime a visual change occurs (which in the real world for an aircraft - the nearest spaceship equivalent would be flaps/control surfaces up/down, nav lights on/off, thrust changes, weapons fired)
In a modern combat sim networked to another in a dog fight situation emits about 200 entity state data units a second and we often run at higher than that if we want very accurate/smooth positional data (i.e. above the minimum recommended)
Oolite Life is now revealed hereSelezen wrote:Apparently I was having a DaddyHoggy moment.
- ClymAngus
- ---- E L I T E ----
- Posts: 2514
- Joined: Tue Jul 08, 2008 12:31 am
- Location: London England
- Contact:
Yes I too have some reservations regarding the social implications of making oolite multiplayer. Sure, programmers will be programmers they'll fill their heads full of how and can, and not for one second waste a moments higher brain function on if or should.Gimli wrote:Has anyone ever played Vendetta Online? It's essentially Elite-like gameplay in a multiplayer setting. I did a little bit of beta-testing a few years ago, but ran out of time, and have never played the commercial release.
If you think the current AI pirates are jerks, just try a trade run through systems full of actual human players who have all the cool toys, and only play to blow up newbies....
I think the one thing everyone's missing here is that a computer opponent doesn't get personal. People do. A computer doesn't pirate your trade then go bragging about it on the forums and add your kill to their banner.
Computers don't sit endlessly behind the beacon and fire 3 missiles point blank up your tail pipe as you warp in, collect all your cargo and (once again) go bragging about it on the forums and add your kill to their banner.
Computers don't turn a fun game into an online bullying session. We have made countless games for this very purpose, some of them are even free. Do we really have to reinvent the wheel AGAIN with oolite?
I worry that in your race for power and glory you'll end up making something painful and unsatisfying to play. Sure your coding will be top notch but sociologists the vast majority of us ain't and it will show.
http://uk.youtube.com/watch?v=8TDSLaDZHLo
The problem (so eloquently put) is choice. Can't stop people choosing to be assholes and assholes ruin any game for everyone else. QED
Yes this is a real problem with other First Person multiplayer games the newbies without all the weapons get picked off for easy points scoring.
People will just sit outside the space station and pick people off
But this is a problem that can be solved by changing legal status of ship which carry out this kind of activity to fugutive then putting a bounty on them.
This way you can self govern.
Unlike battlefield2 where there are two teams and you just sit at the spawn point.
People will just sit outside the space station and pick people off
But this is a problem that can be solved by changing legal status of ship which carry out this kind of activity to fugutive then putting a bounty on them.
This way you can self govern.
Unlike battlefield2 where there are two teams and you just sit at the spawn point.
- DaddyHoggy
- Intergalactic Spam Assassin
- Posts: 8515
- Joined: Tue Dec 05, 2006 9:43 pm
- Location: Newbury, UK
- Contact:
@ClymA - for exactly the reasons you've stated I think the multi-player version should be limited to an arena style combat system.
Take one of the current systems (initially) - fill it full of Asteroids ala SW:TESB, pilots witchspace in and pound the snot out of their fellow commanders - prizes (using the bounty system) awarded for finishing off your oponent(s) - chuck in a few Main stations so that repairs, refueling, rearming can take place - but have limited time - 20s free and then 10Cr per second after that.
Kills go towards both your Elite Rating and special "On-line" rating which is different/separate...
just my 0.02Cr worth
Take one of the current systems (initially) - fill it full of Asteroids ala SW:TESB, pilots witchspace in and pound the snot out of their fellow commanders - prizes (using the bounty system) awarded for finishing off your oponent(s) - chuck in a few Main stations so that repairs, refueling, rearming can take place - but have limited time - 20s free and then 10Cr per second after that.
Kills go towards both your Elite Rating and special "On-line" rating which is different/separate...
just my 0.02Cr worth
Oolite Life is now revealed hereSelezen wrote:Apparently I was having a DaddyHoggy moment.
- ClymAngus
- ---- E L I T E ----
- Posts: 2514
- Joined: Tue Jul 08, 2008 12:31 am
- Location: London England
- Contact:
Well I think we need to raise these things for general discussion (OK maybe doing so here is a bit of a thread jack). But when you start involving a group of people interacting, the social engineering involved become just as complex as the practical construction. Most online experiences try to fulfil a multiplicity of roles, now is this something we want? To not do this requires a clear statement of intent (a la DaddyHoggy) or if we do, it requires treading the fine line between dispassionate on one side and draconian on the other. Too much of eather could potentially alienate players.
As I said this is probably the wrong place to do this. Another tread maybe?
As I said this is probably the wrong place to do this. Another tread maybe?
DaddyHoggy wrote:@ClymA - for exactly the reasons you've stated I think the multi-player version should be limited to an arena style combat system.
Take one of the current systems (initially) - fill it full of Asteroids ala SW:TESB, pilots witchspace in and pound the snot out of their fellow commanders - prizes (using the bounty system) awarded for finishing off your oponent(s) - chuck in a few Main stations so that repairs, refueling, rearming can take place - but have limited time - 20s free and then 10Cr per second after that.
Kills go towards both your Elite Rating and special "On-line" rating which is different/separate...
just my 0.02Cr worth
How about a 30-50km Aegis around the witchpoint, which has to be left within a small-ish period of time after entry, and that ships are not allowed to remain in for more than a certain period of time.
Enforced by either a guard of Vipers or similar, or replacing the witchspace buoy by a large turret with an attitude?
Enforced by either a guard of Vipers or similar, or replacing the witchspace buoy by a large turret with an attitude?
My OXPs via Boxspace or from my Wiki pages .
Thargoid TV
Dropbox Referral Link
Thargoid TV
Dropbox Referral Link
I guess I have not made myself clear here (english is not my first language )
The internal states are updated 25 times a second, but only real changes are propagated to the clients.
Meaning, only if you change the rotation or increase the speed, fire a weapon etc.
E.g. If you have an asteroid flying around it has an initial location and a vector or movement.
It will not change that for it's entire lifetime (at least I suspect firing on it will not change that)
So it will not need to be changed at all.
I doubt you can move your fingers 25 times a second to change the rotation or speed etc.
The internal states are updated 25 times a second, but only real changes are propagated to the clients.
Meaning, only if you change the rotation or increase the speed, fire a weapon etc.
E.g. If you have an asteroid flying around it has an initial location and a vector or movement.
It will not change that for it's entire lifetime (at least I suspect firing on it will not change that)
So it will not need to be changed at all.
I doubt you can move your fingers 25 times a second to change the rotation or speed etc.
DaddyHoggy wrote:What level of fidelity are you expecting to achieve with 25 updates per second? Important if you're trying to shoot the weapon pod sub entities off another ship.
For example using the IEEE 1278 Standard DIS it *recommends* a new state PDU is issued every 1m or 3º of movement (in any plane), plus everytime a visual change occurs (which in the real world for an aircraft - the nearest spaceship equivalent would be flaps/control surfaces up/down, nav lights on/off, thrust changes, weapons fired)
In a modern combat sim networked to another in a dog fight situation emits about 200 entity state data units a second and we often run at higher than that if we want very accurate/smooth positional data (i.e. above the minimum recommended)