mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-12 00:38:44 +07:00
Initial continuous server implementation
This commit is contained in:
@ -66,8 +66,6 @@ public class Logic extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Events.fire(PlayEvent.class);
|
Events.fire(PlayEvent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,18 +80,8 @@ public class NetClient extends Module{
|
|||||||
|
|
||||||
player.isAdmin = false;
|
player.isAdmin = false;
|
||||||
|
|
||||||
Net.setClientLoaded(false);
|
reset();
|
||||||
removed.clear();
|
|
||||||
timeoutTime = 0f;
|
|
||||||
connecting = true;
|
|
||||||
quiet = false;
|
|
||||||
lastSent = 0;
|
|
||||||
lastSnapshotBase = null;
|
|
||||||
currentSnapshot = null;
|
|
||||||
currentSnapshotID = -1;
|
|
||||||
lastSnapshotBaseID = -1;
|
|
||||||
|
|
||||||
ui.chatfrag.clearMessages();
|
|
||||||
ui.loadfrag.hide();
|
ui.loadfrag.hide();
|
||||||
ui.loadfrag.show("$text.connecting.data");
|
ui.loadfrag.show("$text.connecting.data");
|
||||||
|
|
||||||
@ -102,8 +92,6 @@ public class NetClient extends Module{
|
|||||||
Net.disconnect();
|
Net.disconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
Entities.clear();
|
|
||||||
|
|
||||||
ConnectPacket c = new ConnectPacket();
|
ConnectPacket c = new ConnectPacket();
|
||||||
c.name = player.name;
|
c.name = player.name;
|
||||||
c.mobile = mobile;
|
c.mobile = mobile;
|
||||||
@ -161,6 +149,29 @@ public class NetClient extends Module{
|
|||||||
ui.loadfrag.hide();
|
ui.loadfrag.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Remote(variants = Variant.both)
|
||||||
|
public static void onInfoMessage(String message){
|
||||||
|
threads.runGraphics(() -> ui.showInfo(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Remote(variants = Variant.both)
|
||||||
|
public static void onWorldDataBegin(){
|
||||||
|
Entities.clear();
|
||||||
|
ui.chatfrag.clearMessages();
|
||||||
|
Net.setClientLoaded(false);
|
||||||
|
|
||||||
|
threads.runGraphics(() -> {
|
||||||
|
ui.loadfrag.show("$text.connecting.data");
|
||||||
|
|
||||||
|
ui.loadfrag.setButton(() -> {
|
||||||
|
ui.loadfrag.hide();
|
||||||
|
netClient.connecting = false;
|
||||||
|
netClient.quiet = true;
|
||||||
|
Net.disconnect();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Remote(variants = Variant.one)
|
@Remote(variants = Variant.one)
|
||||||
public static void onPositionSet(float x, float y){
|
public static void onPositionSet(float x, float y){
|
||||||
players[0].x = x;
|
players[0].x = x;
|
||||||
@ -285,7 +296,6 @@ public class NetClient extends Module{
|
|||||||
|
|
||||||
//go through each entity
|
//go through each entity
|
||||||
for(int j = 0; j < amount; j++){
|
for(int j = 0; j < amount; j++){
|
||||||
int position = netClient.byteStream.position(); //save position to check read/write correctness
|
|
||||||
int id = input.readInt();
|
int id = input.readInt();
|
||||||
byte typeID = input.readByte();
|
byte typeID = input.readByte();
|
||||||
|
|
||||||
@ -304,11 +314,6 @@ public class NetClient extends Module{
|
|||||||
//read the entity
|
//read the entity
|
||||||
entity.read(input, timestamp);
|
entity.read(input, timestamp);
|
||||||
|
|
||||||
byte readLength = input.readByte();
|
|
||||||
//if(netClient.byteStream.position() - position - 1 != readLength){
|
|
||||||
// throw new RuntimeException("Error reading entity of type '" + group.getType() + "': Read length mismatch [write=" + readLength + ", read=" + (netClient.byteStream.position() - position - 1) + "]");
|
|
||||||
//}
|
|
||||||
|
|
||||||
if(add){
|
if(add){
|
||||||
entity.add();
|
entity.add();
|
||||||
netClient.addRemovedEntity(entity.getID());
|
netClient.addRemovedEntity(entity.getID());
|
||||||
@ -352,6 +357,22 @@ public class NetClient extends Module{
|
|||||||
Timers.runTask(40f, Platform.instance::updateRPC);
|
Timers.runTask(40f, Platform.instance::updateRPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void reset(){
|
||||||
|
Net.setClientLoaded(false);
|
||||||
|
removed.clear();
|
||||||
|
timeoutTime = 0f;
|
||||||
|
connecting = true;
|
||||||
|
quiet = false;
|
||||||
|
lastSent = 0;
|
||||||
|
lastSnapshotBase = null;
|
||||||
|
currentSnapshot = null;
|
||||||
|
currentSnapshotID = -1;
|
||||||
|
lastSnapshotBaseID = -1;
|
||||||
|
|
||||||
|
Entities.clear();
|
||||||
|
ui.chatfrag.clearMessages();
|
||||||
|
}
|
||||||
|
|
||||||
public void beginConnecting(){
|
public void beginConnecting(){
|
||||||
connecting = true;
|
connecting = true;
|
||||||
}
|
}
|
||||||
|
@ -190,15 +190,7 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
trace.playerid = player.id;
|
trace.playerid = player.id;
|
||||||
|
|
||||||
//TODO try DeflaterOutputStream
|
sendWorldData(player, id);
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
|
||||||
DeflaterOutputStream def = new DeflaterOutputStream(stream);
|
|
||||||
NetworkIO.writeWorld(player, def);
|
|
||||||
WorldStream data = new WorldStream();
|
|
||||||
data.stream = new ByteArrayInputStream(stream.toByteArray());
|
|
||||||
Net.sendStream(id, data);
|
|
||||||
|
|
||||||
Log.info("Packed {0} uncompressed bytes of WORLD data.", stream.size());
|
|
||||||
|
|
||||||
Platform.instance.updateRPC();
|
Platform.instance.updateRPC();
|
||||||
});
|
});
|
||||||
@ -317,6 +309,17 @@ public class NetServer extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendWorldData(Player player, int clientID){
|
||||||
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
|
DeflaterOutputStream def = new DeflaterOutputStream(stream);
|
||||||
|
NetworkIO.writeWorld(player, def);
|
||||||
|
WorldStream data = new WorldStream();
|
||||||
|
data.stream = new ByteArrayInputStream(stream.toByteArray());
|
||||||
|
Net.sendStream(clientID, data);
|
||||||
|
|
||||||
|
Log.info("Packed {0} compressed bytes of world data.", stream.size());
|
||||||
|
}
|
||||||
|
|
||||||
public static void onDisconnect(Player player){
|
public static void onDisconnect(Player player){
|
||||||
if(player.con.hasConnected){
|
if(player.con.hasConnected){
|
||||||
Call.sendMessage("[accent]" + player.name + "[accent] has disconnected.");
|
Call.sendMessage("[accent]" + player.name + "[accent] has disconnected.");
|
||||||
@ -483,7 +486,6 @@ public class NetServer extends Module{
|
|||||||
int length = syncStream.position() - position; //length must always be less than 127 bytes
|
int length = syncStream.position() - position; //length must always be less than 127 bytes
|
||||||
if(length > 127)
|
if(length > 127)
|
||||||
throw new RuntimeException("Write size for entity of type " + group.getType() + " must not exceed 127!");
|
throw new RuntimeException("Write size for entity of type " + group.getType() + " must not exceed 127!");
|
||||||
dataStream.writeByte(length);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
|||||||
|
|
||||||
if(target != null) behavior();
|
if(target != null) behavior();
|
||||||
|
|
||||||
if(!isWave){
|
if(!isWave && !isFlying()){
|
||||||
x = Mathf.clamp(x, 0, world.width() * tilesize);
|
x = Mathf.clamp(x, 0, world.width() * tilesize);
|
||||||
y = Mathf.clamp(y, 0, world.height() * tilesize);
|
y = Mathf.clamp(y, 0, world.height() * tilesize);
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,8 @@ public class NetworkIO{
|
|||||||
i += consecutives;
|
i += consecutives;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stream.write(Team.all.length);
|
||||||
|
|
||||||
//write team data
|
//write team data
|
||||||
for(Team team : Team.all){
|
for(Team team : Team.all){
|
||||||
TeamData data = state.teams.get(team);
|
TeamData data = state.teams.get(team);
|
||||||
|
@ -14,7 +14,7 @@ public class ItemImage extends Stack{
|
|||||||
public ItemImage(TextureRegion region, Supplier<CharSequence> text){
|
public ItemImage(TextureRegion region, Supplier<CharSequence> text){
|
||||||
Table t = new Table().left().bottom();
|
Table t = new Table().left().bottom();
|
||||||
|
|
||||||
t.label(text).color(Color.DARK_GRAY).padBottom(-22).get().setFontScale(Unit.dp.scl(0.5f));
|
t.label(text).color(Color.DARK_GRAY).padBottom(-21).get().setFontScale(Unit.dp.scl(0.5f));
|
||||||
t.row();
|
t.row();
|
||||||
t.label(text).get().setFontScale(Unit.dp.scl(0.5f));
|
t.label(text).get().setFontScale(Unit.dp.scl(0.5f));
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ public class ItemImage extends Stack{
|
|||||||
public ItemImage(ItemStack stack){
|
public ItemImage(ItemStack stack){
|
||||||
Table t = new Table().left().bottom();
|
Table t = new Table().left().bottom();
|
||||||
|
|
||||||
t.add(stack.amount + "").color(Color.DARK_GRAY).padBottom(-22).get().setFontScale(Unit.dp.scl(0.5f));
|
t.add(stack.amount + "").color(Color.DARK_GRAY).padBottom(-21).get().setFontScale(Unit.dp.scl(0.5f));
|
||||||
t.row();
|
t.row();
|
||||||
t.add(stack.amount + "").get().setFontScale(Unit.dp.scl(0.5f));
|
t.add(stack.amount + "").get().setFontScale(Unit.dp.scl(0.5f));
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package io.anuke.mindustry.world.blocks.storage;
|
package io.anuke.mindustry.world.blocks.storage;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
|
||||||
import io.anuke.annotations.Annotations.Loc;
|
import io.anuke.annotations.Annotations.Loc;
|
||||||
import io.anuke.annotations.Annotations.Remote;
|
import io.anuke.annotations.Annotations.Remote;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
@ -38,12 +37,7 @@ import java.io.IOException;
|
|||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class CoreBlock extends StorageBlock{
|
public class CoreBlock extends StorageBlock{
|
||||||
private static Rectangle rect = new Rectangle();
|
|
||||||
|
|
||||||
protected int timerSupply = timers++;
|
|
||||||
|
|
||||||
protected float supplyRadius = 50f;
|
protected float supplyRadius = 50f;
|
||||||
protected float supplyInterval = 5f;
|
|
||||||
protected float droneRespawnDuration = 60 * 6;
|
protected float droneRespawnDuration = 60 * 6;
|
||||||
protected UnitType droneType = UnitTypes.drone;
|
protected UnitType droneType = UnitTypes.drone;
|
||||||
|
|
||||||
|
@ -9,13 +9,16 @@ import io.anuke.mindustry.game.Difficulty;
|
|||||||
import io.anuke.mindustry.game.EventType.GameOverEvent;
|
import io.anuke.mindustry.game.EventType.GameOverEvent;
|
||||||
import io.anuke.mindustry.game.GameMode;
|
import io.anuke.mindustry.game.GameMode;
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.gen.Call;
|
|
||||||
import io.anuke.mindustry.maps.Map;
|
|
||||||
import io.anuke.mindustry.io.SaveIO;
|
|
||||||
import io.anuke.mindustry.game.Version;
|
import io.anuke.mindustry.game.Version;
|
||||||
import io.anuke.mindustry.net.*;
|
import io.anuke.mindustry.gen.Call;
|
||||||
|
import io.anuke.mindustry.io.SaveIO;
|
||||||
|
import io.anuke.mindustry.maps.Map;
|
||||||
|
import io.anuke.mindustry.net.Administration;
|
||||||
import io.anuke.mindustry.net.Administration.PlayerInfo;
|
import io.anuke.mindustry.net.Administration.PlayerInfo;
|
||||||
|
import io.anuke.mindustry.net.EditLog;
|
||||||
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.Packets.KickReason;
|
import io.anuke.mindustry.net.Packets.KickReason;
|
||||||
|
import io.anuke.mindustry.net.TraceInfo;
|
||||||
import io.anuke.mindustry.type.Item;
|
import io.anuke.mindustry.type.Item;
|
||||||
import io.anuke.mindustry.type.ItemType;
|
import io.anuke.mindustry.type.ItemType;
|
||||||
import io.anuke.mindustry.ui.fragments.DebugFragment;
|
import io.anuke.mindustry.ui.fragments.DebugFragment;
|
||||||
@ -87,9 +90,9 @@ public class ServerControl extends Module{
|
|||||||
|
|
||||||
Events.on(GameOverEvent.class, () -> {
|
Events.on(GameOverEvent.class, () -> {
|
||||||
info("Game over!");
|
info("Game over!");
|
||||||
netServer.kickAll(KickReason.gameover);
|
|
||||||
|
|
||||||
if(mode != ShuffleMode.off){
|
if(mode != ShuffleMode.off){
|
||||||
|
Call.onInfoMessage("Game over!");
|
||||||
if(world.getSector() == null){
|
if(world.getSector() == null){
|
||||||
if(world.maps().all().size > 0){
|
if(world.maps().all().size > 0){
|
||||||
Array<Map> maps = mode == ShuffleMode.both ? world.maps().all() :
|
Array<Map> maps = mode == ShuffleMode.both ? world.maps().all() :
|
||||||
@ -103,9 +106,9 @@ public class ServerControl extends Module{
|
|||||||
|
|
||||||
info("Selected next map to be {0}.", map.name);
|
info("Selected next map to be {0}.", map.name);
|
||||||
|
|
||||||
logic.reset();
|
Map fmap = map;
|
||||||
world.loadMap(map);
|
|
||||||
state.set(State.playing);
|
play(() -> world.loadMap(fmap));
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(gameOvers >= 2){
|
if(gameOvers >= 2){
|
||||||
@ -118,6 +121,7 @@ public class ServerControl extends Module{
|
|||||||
info("Re-trying sector map: {0} {1}", Settings.getInt("sector_x"), Settings.getInt("sector_y"));
|
info("Re-trying sector map: {0} {1}", Settings.getInt("sector_x"), Settings.getInt("sector_y"));
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
netServer.kickAll(KickReason.gameover);
|
||||||
state.set(State.menu);
|
state.set(State.menu);
|
||||||
Net.closeServer();
|
Net.closeServer();
|
||||||
}
|
}
|
||||||
@ -845,8 +849,26 @@ public class ServerControl extends Module{
|
|||||||
if(world.sectors().get(x, y) == null){
|
if(world.sectors().get(x, y) == null){
|
||||||
world.sectors().createSector(x, y);
|
world.sectors().createSector(x, y);
|
||||||
}
|
}
|
||||||
world.loadSector(world.sectors().get(x, y));
|
|
||||||
|
world.sectors().get(x, y).completedMissions = 0;
|
||||||
|
|
||||||
|
play(() -> world.loadSector(world.sectors().get(x, y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void play(Runnable run){
|
||||||
|
Array<Player> players = new Array<>();
|
||||||
|
for(Player p : playerGroup.all()){
|
||||||
|
players.add(p);
|
||||||
|
p.setDead(true);
|
||||||
|
}
|
||||||
|
logic.reset();
|
||||||
|
Call.onWorldDataBegin();
|
||||||
|
run.run();
|
||||||
logic.play();
|
logic.play();
|
||||||
|
for(Player p : players){
|
||||||
|
p.add();
|
||||||
|
netServer.sendWorldData(p, p.con.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void host(){
|
private void host(){
|
||||||
@ -864,6 +886,7 @@ public class ServerControl extends Module{
|
|||||||
if(state.is(State.playing) && world.getSector() != null){
|
if(state.is(State.playing) && world.getSector() != null){
|
||||||
//all assigned missions are complete
|
//all assigned missions are complete
|
||||||
if(world.getSector().completedMissions >= world.getSector().missions.size){
|
if(world.getSector().completedMissions >= world.getSector().missions.size){
|
||||||
|
Log.info("Mission complete.");
|
||||||
world.sectors().completeSector(world.getSector().x, world.getSector().y);
|
world.sectors().completeSector(world.getSector().x, world.getSector().y);
|
||||||
world.sectors().save();
|
world.sectors().save();
|
||||||
gameOvers = 0;
|
gameOvers = 0;
|
||||||
|
Reference in New Issue
Block a user