mirror of
https://github.com/wassname/GarageServer.IO.git
synced 2026-06-27 16:10:34 +08:00
Resolved: #12 Regions - limit state bandwidth
This commit is contained in:
@@ -11,6 +11,7 @@ A simple, lightweight, HTML multiplayer game server (and client) for Node.js
|
||||
- Server State History
|
||||
- Server and Client Messaging
|
||||
- Server Reconciliation
|
||||
- Region Broadcasting
|
||||
- Works with any rendering and/or physics engine
|
||||
|
||||
## Install
|
||||
|
||||
@@ -236,4 +236,30 @@ GarageServerIO.sendPlayersEvent(data)
|
||||
```
|
||||
Allows server to broadcast events to all players. Use this to make custom calls to GarageServer.IO clients for your game.
|
||||
`data` **object literal**
|
||||
Object containing all properties specific to the custom event.
|
||||
Object containing all properties specific to the custom event.
|
||||
#### setPlayerRegion
|
||||
---
|
||||
```js
|
||||
GarageServerIO.setPlayerRegion(id, region)
|
||||
```
|
||||
Sets the player region. GarageServer.IO will broadcast the state of players and entities who share the same region. NOTE: This will implicitly enable GarageServer.IO region broadcasting - only those players and entities with regions with be notified of state. Use `clearRegions` to revert region broadcasting.
|
||||
`id` **string**
|
||||
Id of the player to receive event.
|
||||
`region` **string**
|
||||
Name of the region.
|
||||
#### setEntityRegion
|
||||
---
|
||||
```js
|
||||
GarageServerIO.setEntityRegion(id, region)
|
||||
```
|
||||
Sets the entity region. GarageServer.IO will broadcast the state of players and entities who share the same region. NOTE: This will implicitly enable GarageServer.IO region broadcasting - only those players and entities with regions with be notified of state. Use `clearRegions` to revert region broadcasting.
|
||||
`id` **string**
|
||||
Id of the entity to receive event.
|
||||
`region` **string**
|
||||
Name of the region.
|
||||
#### clearRegions
|
||||
---
|
||||
```js
|
||||
GarageServerIO.clearRegions()
|
||||
```
|
||||
Clears all regions associated with players and entities. GarageServer.IO will default back to broadcasting state to all players.
|
||||
@@ -32,5 +32,10 @@ EntityController.prototype = {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
clearRegions: function () {
|
||||
for (var i = 0; i < this.entities.length; i ++) {
|
||||
this.entities[i].setRegion('');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -9,11 +9,11 @@ function PlayerController (maxHistorySecondBuffer) {
|
||||
|
||||
PlayerController.prototype = Object.create(entityController.prototype);
|
||||
|
||||
PlayerController.prototype.add = function (client) {
|
||||
PlayerController.prototype.add = function (socket) {
|
||||
var newPlayer, playerFound = false;
|
||||
|
||||
this.entities.some(function (player) {
|
||||
if (player.client.id === client.id) {
|
||||
if (player.id === socket.id) {
|
||||
newPlayer = player;
|
||||
playerFound = true;
|
||||
return true;
|
||||
@@ -21,7 +21,7 @@ PlayerController.prototype.add = function (client) {
|
||||
});
|
||||
|
||||
if (!playerFound) {
|
||||
newPlayer = new player(client, this.maxHistorySecondBuffer);
|
||||
newPlayer = new player(socket, this.maxHistorySecondBuffer);
|
||||
this.entities.push(newPlayer);
|
||||
}
|
||||
return newPlayer;
|
||||
@@ -29,7 +29,7 @@ PlayerController.prototype.add = function (client) {
|
||||
|
||||
PlayerController.prototype.addInput = function (id, input, sequence, time) {
|
||||
this.entities.some(function (player) {
|
||||
if (player.client.id === id) {
|
||||
if (player.id === id) {
|
||||
player.inputs.push({ input: input, seq: sequence, time: time });
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ function Entity (id, maxHistorySecondBuffer) {
|
||||
this.id = id;
|
||||
this.maxHistorySecondBuffer = maxHistorySecondBuffer;
|
||||
this.stateHistory = [];
|
||||
this.region = '';
|
||||
}
|
||||
|
||||
Entity.prototype = {
|
||||
@@ -31,5 +32,8 @@ Entity.prototype = {
|
||||
if (spliceTo > 0) {
|
||||
this.stateHistory.splice(0, spliceTo);
|
||||
}
|
||||
},
|
||||
setRegion: function (region) {
|
||||
this.region = region;
|
||||
}
|
||||
};
|
||||
@@ -2,14 +2,20 @@ var entity = require('./entity');
|
||||
|
||||
exports = module.exports = Player;
|
||||
|
||||
function Player (client, maxHistorySecondBuffer) {
|
||||
entity.call(this, client.id, maxHistorySecondBuffer);
|
||||
this.client = client;
|
||||
function Player (socket, maxHistorySecondBuffer) {
|
||||
entity.call(this, socket.id, maxHistorySecondBuffer);
|
||||
this.socket = socket;
|
||||
this.inputs = [];
|
||||
}
|
||||
|
||||
Player.prototype = Object.create(entity.prototype);
|
||||
|
||||
Player.prototype.setRegion = function (region) {
|
||||
this.socket.join(region);
|
||||
this.socket.leave(this.region);
|
||||
this.region = region;
|
||||
};
|
||||
|
||||
Player.prototype.addState = function (state, executionTime) {
|
||||
this.addHistory(state, executionTime);
|
||||
this.sequence += this.inputs.length;
|
||||
|
||||
+18
-2
@@ -37,8 +37,12 @@ function GarageServer(socketio, options) {
|
||||
this.socketPath = namespace;
|
||||
this.io = socketio;
|
||||
this.registerSocketEvents(options);
|
||||
this.game = new garageServerGame(options, function (state) {
|
||||
socketio.of(namespace).emit('update' ,state);
|
||||
this.game = new garageServerGame(options, function (state, region) {
|
||||
if (!region) {
|
||||
socketio.of(namespace).emit('update' ,state);
|
||||
} else {
|
||||
socketio.of(namespace).in(region).emit('update' ,state);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -163,6 +167,18 @@ GarageServer.prototype.sendPlayersEvent = function (data) {
|
||||
this.io.of(this.socketPath).emit('event', data);
|
||||
};
|
||||
|
||||
GarageServer.prototype.setPlayerRegion = function (id, region) {
|
||||
this.game.setPlayerRegion(id, region);
|
||||
};
|
||||
|
||||
GarageServer.prototype.setEntityRegion = function (id, region) {
|
||||
this.game.setEntityRegion(id, region);
|
||||
};
|
||||
|
||||
GarageServer.prototype.clearRegions = function () {
|
||||
this.game.clearRegions();
|
||||
};
|
||||
|
||||
exports.createGarageServer = function (io, options) {
|
||||
return new GarageServer(io, options);
|
||||
};
|
||||
+64
-20
@@ -11,6 +11,7 @@ function GarageServerGame(options, broadcastCallback) {
|
||||
this.playerController = new playerController(this.options.maxHistorySecondBuffer ? this.options.maxHistorySecondBuffer : 1000);
|
||||
this.entityController = new entityController(this.options.maxHistorySecondBuffer ? this.options.maxHistorySecondBuffer : 1000);
|
||||
this.broadcastCallback = broadcastCallback;
|
||||
this.regions = [];
|
||||
}
|
||||
|
||||
GarageServerGame.prototype.start = function () {
|
||||
@@ -25,13 +26,20 @@ GarageServerGame.prototype.stop = function () {
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.broadcastState = function () {
|
||||
var currentTime = new Date().getTime() - this.startTime,
|
||||
var i = 0, currentTime = new Date().getTime() - this.startTime,
|
||||
state = { time: currentTime, playerStates: [], entityStates: [] };
|
||||
|
||||
state.playerStates = this.getState(this.playerController);
|
||||
state.entityStates = this.getState(this.entityController);
|
||||
|
||||
this.broadcastCallback(state);
|
||||
if (this.regions.length > 0) {
|
||||
for (i = 0; i < this.regions.length; i ++) {
|
||||
state.playerStates = this.getStateByRegion(this.playerController, this.regions[i]);
|
||||
state.entityStates = this.getStateByRegion(this.entityController, this.regions[i]);
|
||||
this.broadcastCallback(state, this.regions[i]);
|
||||
}
|
||||
} else {
|
||||
state.playerStates = this.getState(this.playerController);
|
||||
state.entityStates = this.getState(this.entityController);
|
||||
this.broadcastCallback(state);
|
||||
}
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.getState = function (controller) {
|
||||
@@ -42,6 +50,16 @@ GarageServerGame.prototype.getState = function (controller) {
|
||||
return states;
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.getStateByRegion = function (controller, region) {
|
||||
var states = [];
|
||||
controller.entities.forEach(function (entity) {
|
||||
if (entity.region === region) {
|
||||
states.push([ entity.id, entity.state, entity.sequence ]);
|
||||
}
|
||||
});
|
||||
return states;
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.getPlayers = function () {
|
||||
var list = [];
|
||||
this.playerController.entities.forEach(function (player) {
|
||||
@@ -58,18 +76,6 @@ GarageServerGame.prototype.getEntities = function () {
|
||||
return list;
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.getPlayer = function (id) {
|
||||
var playerFound;
|
||||
|
||||
this.playerController.entities.some(function (player) {
|
||||
if (player.id === id) {
|
||||
playerFound = player;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return playerFound;
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.updatePlayerState = function (id, state) {
|
||||
this.updateState(this.playerController, id, state);
|
||||
};
|
||||
@@ -89,8 +95,8 @@ GarageServerGame.prototype.updateState = function (controller, id, state) {
|
||||
});
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.addPlayer = function (client) {
|
||||
this.playerController.add(client);
|
||||
GarageServerGame.prototype.addPlayer = function (socket) {
|
||||
this.playerController.add(socket);
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.removePlayer = function (id) {
|
||||
@@ -112,8 +118,46 @@ GarageServerGame.prototype.addPlayerInput = function (id, input, sequence, time)
|
||||
GarageServerGame.prototype.sendPlayerEvent = function (id, data) {
|
||||
this.playerController.entities.some(function (player) {
|
||||
if (player.id === id) {
|
||||
player.client.emit('event', data);
|
||||
player.socket.emit('event', data);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.setPlayerRegion = function (id, region) {
|
||||
this.setRegion(this.playerController, id, region);
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.setEntityRegion = function (id, region) {
|
||||
this.setRegion(this.entityController, id, region);
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.setRegion = function (controller, id, region) {
|
||||
var self = this;
|
||||
controller.entities.some(function (entity) {
|
||||
if (entity.id === id) {
|
||||
entity.setRegion(region);
|
||||
self.updateRegions(region);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.updateRegions = function (region) {
|
||||
var regionFound = false;
|
||||
|
||||
this.regions.forEach(function (item) {
|
||||
if (item === region) {
|
||||
regionFound = true;
|
||||
}
|
||||
});
|
||||
if (!regionFound) {
|
||||
this.regions.push(region);
|
||||
}
|
||||
};
|
||||
|
||||
GarageServerGame.prototype.clearRegions = function () {
|
||||
this.regions = [];
|
||||
this.entityController.clearRegions();
|
||||
this.playerController.clearRegions();
|
||||
};
|
||||
Reference in New Issue
Block a user