mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 07:04:52 +09:00
Live updates to map as things are placed or removed
This commit is contained in:
1 parent
9ae20886b3
commit
51bb9f4d71
5 files changed
+91
-29
No files matched your search
@@ -621,8 +621,18 @@ class slaveMapper {
|
||||
mapRequesters[data.requesterID].socket.emit("displayChunk", data);
|
||||
});
|
||||
// slaveMapper sent us an entity update, process
|
||||
this.socket.on("sendEntity", function(entity){
|
||||
mapRequesters[entity.requesterID].socket.emit("displayEntity", entity);
|
||||
this.socket.on("sendEntity", entity => {
|
||||
Object.keys(mapRequesters).forEach(requesterName => {
|
||||
let requester = mapRequesters[requesterName];
|
||||
if(requester.lastBeat < (Date.now() - 30000)){
|
||||
console.log("There are currently "+Object.keys(mapRequesters).length+" map requesters, deleting one on timeout");
|
||||
delete mapRequesters[requesterName]; // we have to use the full name here or we will only kill the pointer
|
||||
}
|
||||
if(requester.instanceID == this.instanceID){
|
||||
// this mapRequester is listening to this slaveMapper, so we send it updates
|
||||
requester.socket.emit("displayEntity", entity);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -632,7 +642,12 @@ class mapRequester {
|
||||
this.requesterID = requesterID;
|
||||
this.socket = socket;
|
||||
this.instanceID = instanceID;
|
||||
this.lastBeat = Date.now();
|
||||
|
||||
this.socket.on("heartbeat", () => {
|
||||
// we aren't ready to die yet apparently
|
||||
this.lastBeat = Date.now();
|
||||
});
|
||||
this.socket.on("requestChunk", loc => {
|
||||
loc.requesterID = this.requesterID;
|
||||
let instanceID = loc.instanceID || this.instanceID;
|
||||
@@ -659,7 +674,7 @@ io.on('connection', function (socket) {
|
||||
// data {instanceID:""}
|
||||
let requesterID = Math.random().toString();
|
||||
mapRequesters[requesterID] = new mapRequester(requesterID, socket, data.instanceID);
|
||||
|
||||
socket.emit("mapRequesterReady", true);
|
||||
console.log("SOCKET registered map requester for "+data.instanceID);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -48,7 +48,7 @@ module.exports = class chunkStore {
|
||||
});
|
||||
});
|
||||
resolve();
|
||||
this.eventEmitter.emit("change", [{x,y}]);
|
||||
this.eventEmitter.emit("change", {x,y});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -58,7 +58,6 @@ module.exports = class chunkStore {
|
||||
this.db.find({x:Math.floor(x), y:Math.floor(y)}, (err, docs) => {
|
||||
if(err) reject(err);
|
||||
resolve(docs);
|
||||
this.eventEmitter.emit("change", docs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,12 +12,23 @@ class remoteMap {
|
||||
|
||||
// initialize chunk database
|
||||
this.chunkMap = new chunkStore(this.config.unique, 64, "./database/chunkStore/");
|
||||
this.chunkMap.onEntityChange(entity => {
|
||||
console.log("Entity changed: ")
|
||||
console.log(entity);
|
||||
// check valid coordinates (dunno what could go wrong, but can never be too sure)
|
||||
if(entity && entity.x !== undefined && !isNaN(Number(entity.x)) && entity.y !== undefined && !isNaN(Number(entity.y))){
|
||||
this.socket.emit("sendEntity", entity);
|
||||
}
|
||||
});
|
||||
|
||||
// set up websocket communication and handle requests from web interface users (which are going through master)
|
||||
// socket should be a global
|
||||
this.socket = ioClient("http://"+this.config.masterIP+":"+this.config.masterPort);
|
||||
this.socket.on("hello", data => {
|
||||
this.socket.emit("registerSlaveMapper", {instanceID: this.config.unique});
|
||||
setInterval(()=>{
|
||||
this.socket.emit("heartbeat"); // send our heartbeat to prevent being assumed dead
|
||||
},10000);
|
||||
});
|
||||
this.socket.on("getChunk", req => {
|
||||
console.log("getChunk is not supported!");
|
||||
@@ -27,11 +38,11 @@ class remoteMap {
|
||||
});*/
|
||||
});
|
||||
this.socket.on("getEntity", req => {
|
||||
if(req.requesterID && req.x && !isNaN(Number(req.x)) && req.y && !isNaN(Number(req.y))){
|
||||
// check for valid coordinates
|
||||
if(req.x !== undefined && !isNaN(Number(req.x)) && req.y !== undefined && !isNaN(Number(req.y))){
|
||||
this.chunkMap.getEntity(req.x, req.y).then(entities => {
|
||||
if(entities && entities.length > 0){
|
||||
entities.forEach(entity => {
|
||||
entity.requesterID = req.requesterID;
|
||||
this.socket.emit("sendEntity", entity);
|
||||
});
|
||||
}
|
||||
@@ -45,9 +56,8 @@ class remoteMap {
|
||||
}
|
||||
scriptOutput(data){
|
||||
if(data){
|
||||
//this.messageInterface(data);
|
||||
this.messageInterface(data);
|
||||
// express-transport-belt -35.5 -14.5
|
||||
|
||||
data = data.split(" ");
|
||||
if(data && data[0] == undefined){
|
||||
console.log("empty: ");
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<%- include("sidebar.html") %>
|
||||
<div id="body">
|
||||
<h2>remoteMap</h2>
|
||||
<canvas id="remoteMap" width="2500" height="2500" style="border:1px solid #000000;">
|
||||
<canvas id="remoteMap" width="1024" height="1024" style="border:1px solid #000000;">
|
||||
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
+57
-19
@@ -1,7 +1,23 @@
|
||||
function getParameterByName(name, url) {
|
||||
if (!url) url = window.location.href;
|
||||
name = name.replace(/[\[\]]/g, "\\$&");
|
||||
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
|
||||
results = regex.exec(url);
|
||||
if (!results) return null;
|
||||
if (!results[2]) return '';
|
||||
return decodeURIComponent(results[2].replace(/\+/g, " "));
|
||||
}
|
||||
|
||||
var socket = io.connect('http://localhost:8080');
|
||||
socket.on('hello', function (data) {
|
||||
console.log(data);
|
||||
socket.emit("registerMapRequester", {instanceID: '1611985668'});
|
||||
socket.emit("registerMapRequester", {instanceID: getParameterByName("instanceID")});
|
||||
socket.on("mapRequesterReady", function(){
|
||||
setInterval(()=>{
|
||||
socket.emit("heartbeat"); // send our heartbeat to prevent being assumed dead
|
||||
},10000);
|
||||
requestMapDraw();
|
||||
});
|
||||
|
||||
socket.on("displayChunk", function(chunk){
|
||||
console.log(chunk);
|
||||
@@ -14,14 +30,11 @@ socket.on('hello', function (data) {
|
||||
});
|
||||
|
||||
function requestChunk(x,y){
|
||||
socket.emit('requestChunk', {x:x, y:y, instanceID: '1611985668'});
|
||||
socket.emit('requestChunk', {x:x, y:y, instanceID: getParameterByName("instanceID")});
|
||||
}
|
||||
setTimeout(function(){
|
||||
canvas = document.getElementById("remoteMap");
|
||||
ctx = canvas.getContext("2d");
|
||||
ctx.beginPath();
|
||||
ctx.arc(95,50,40,0,2*Math.PI);
|
||||
ctx.stroke();
|
||||
ctx.font = "30px Arial";
|
||||
ctx.fillText("Hello World",10,50);
|
||||
|
||||
@@ -31,11 +44,12 @@ setTimeout(function(){
|
||||
};
|
||||
img.src = 'https://wiki.factorio.com/images/Lab.png';
|
||||
|
||||
requestChunk(0, -1);
|
||||
}, 500);
|
||||
}, 1);
|
||||
entityImages = {};
|
||||
/*
|
||||
entityImages["express-transport-belt"] = new Image();
|
||||
entityImages["express-transport-belt"].src = 'https://wiki.factorio.com/images/Express_transport_belt.png';
|
||||
*/
|
||||
|
||||
// map view position, top left corner (or another corner?)
|
||||
playerPosition = {
|
||||
@@ -50,28 +64,49 @@ function requestMapDraw(){
|
||||
let yHigh = yLow+64;
|
||||
for(let x = xLow; x < xHigh; x++){
|
||||
for(let y = yLow; y < yHigh; y++){
|
||||
socket.emit("requestEntity", {x, y, instanceID: '1611985668'});
|
||||
socket.emit("requestEntity", {x, y, instanceID: getParameterByName("instanceID")});
|
||||
}
|
||||
}
|
||||
}
|
||||
function drawEntity(entity, ctx){
|
||||
function drawEntity(entity){
|
||||
if(entity.x && entity.y){
|
||||
if(entity.entity && entity.entity.name && typeof entity.entity.name == "string"){
|
||||
let name = entity.entity.name;
|
||||
let xPos = (entity.x * 16) - playerPosition.x;
|
||||
let yPos = (entity.y * 16) - playerPosition.y;
|
||||
if(!entityImages[name]){
|
||||
// download the entityImages
|
||||
entityImages[name] = new Image();
|
||||
entityImages[name].onload = function(){
|
||||
ctx.drawImage(entityImages[name], xPos, yPos, 16, 16);
|
||||
console.log("Drawing "+name+" at X: "+xPos+", Y: "+yPos);
|
||||
// download the entityImages and add stuff to queue
|
||||
entityImages[name] = {};
|
||||
entityImages[name].img = new Image();
|
||||
entityImages[name].queue = [];
|
||||
entityImages[name].queue.push(entity);
|
||||
entityImages[name].loaded = false;
|
||||
entityImages[name].img.onload = function(){
|
||||
// process queue and display
|
||||
console.log("Image loaded!");
|
||||
entityImages[name].loaded = true;
|
||||
entityImages[name].queue.forEach(entity => {
|
||||
entityImages[name].draw(entity);
|
||||
});
|
||||
entityImages[name].queue = [];
|
||||
}
|
||||
entityImages[name].src = getImageFromName(name);
|
||||
entityImages[name].draw = function(entity){
|
||||
if(this.loaded){
|
||||
let name = entity.entity.name;
|
||||
let xPos = (entity.x * 16) - playerPosition.x;
|
||||
let yPos = (entity.y * 16) - playerPosition.y;
|
||||
ctx.drawImage(entityImages[name].img, xPos, yPos, 16, 16);
|
||||
console.log("Drawing "+name+" at X: "+xPos+", Y: "+yPos);
|
||||
} else {
|
||||
this.queue.push(entity);
|
||||
}
|
||||
}
|
||||
entityImages[name].img.src = getImageFromName(name);
|
||||
} else {
|
||||
entityImages[name].draw(entity);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new Error(entity);
|
||||
// we got an empty coordinate pair, that usually means this tile was occupied before but is empty now
|
||||
console.log("Clearing at X: "+entity.x+", Y: "+entity.y);
|
||||
ctx.clearRect(entity.x * 16, entity.y * 16, 16, 16);
|
||||
}
|
||||
} else {
|
||||
throw new Error("drawEntity on entity without x and y coordinates")
|
||||
@@ -96,3 +131,6 @@ function drawChunk(chunk, ctx){
|
||||
});
|
||||
});
|
||||
}
|
||||
function clear(){
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
Reference in new issue
Block a user