mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-03-12 10:59:22 +07:00
Player limit / Server mode display / Crash fixes / More save info
This commit is contained in:
parent
9cc76a148b
commit
a7bfe18f4a
@ -64,8 +64,8 @@ techtree = Tech Tree
|
||||
research.list = [lightgray]Research:
|
||||
research = Research
|
||||
researched = [lightgray]{0} researched.
|
||||
players = {0} players online
|
||||
players.single = {0} player online
|
||||
players = {0} players
|
||||
players.single = {0} player
|
||||
server.closing = [accent]Closing server...
|
||||
server.kicked.kick = You have been kicked from the server!
|
||||
server.kicked.whitelist = You are not whitelisted here.
|
||||
@ -75,6 +75,7 @@ server.kicked.clientOutdated = Outdated client! Update your game!
|
||||
server.kicked.serverOutdated = Outdated server! Ask the host to update!
|
||||
server.kicked.banned = You are banned on this server.
|
||||
server.kicked.typeMismatch = This server is not compatible with your build type.
|
||||
server.kicked.playerLimit = This server is full. Wait for an empty slot.
|
||||
server.kicked.recentKick = You have been kicked recently.\nWait before connecting again.
|
||||
server.kicked.nameInUse = There is someone with that name\nalready on this server.
|
||||
server.kicked.nameEmpty = Your chosen name is invalid.
|
||||
@ -110,7 +111,7 @@ server.edit = Edit Server
|
||||
server.outdated = [crimson]Outdated Server![]
|
||||
server.outdated.client = [crimson]Outdated Client![]
|
||||
server.version = [gray]v{0} {1}
|
||||
server.custombuild = [yellow]Custom Build
|
||||
server.custombuild = [accent]Custom Build
|
||||
confirmban = Are you sure you want to ban this player?
|
||||
confirmkick = Are you sure you want to kick this player?
|
||||
confirmunban = Are you sure you want to unban this player?
|
||||
@ -155,7 +156,7 @@ off = Off
|
||||
save.autosave = Autosave: {0}
|
||||
save.map = Map: {0}
|
||||
save.wave = Wave {0}
|
||||
save.difficulty = Difficulty: {0}
|
||||
save.mode = Gamemode: {0}
|
||||
save.date = Last Saved: {0}
|
||||
save.playtime = Playtime: {0}
|
||||
warning = Warning.
|
||||
|
@ -84,6 +84,8 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
||||
|
||||
@Override
|
||||
public void resize(int width, int height){
|
||||
if(assets == null) return;
|
||||
|
||||
if(!assets.isFinished()){
|
||||
Draw.proj().setOrtho(0, 0, width, height);
|
||||
}else{
|
||||
|
@ -500,6 +500,7 @@ public class Blocks implements ContentList{
|
||||
|
||||
consumes.items(new ItemStack(Items.thorium, 4), new ItemStack(Items.sand, 10));
|
||||
consumes.power(5f);
|
||||
itemCapacity = 20;
|
||||
|
||||
int bottomRegion = reg("-bottom"), weaveRegion = reg("-weave");
|
||||
|
||||
|
@ -48,6 +48,10 @@ public class Control implements ApplicationListener, Loadable{
|
||||
private boolean wasPaused = false;
|
||||
|
||||
public Control(){
|
||||
saves = new Saves();
|
||||
tutorial = new Tutorial();
|
||||
music = new MusicControl();
|
||||
|
||||
Events.on(StateChangeEvent.class, event -> {
|
||||
if((event.from == State.playing && event.to == State.menu) || (event.from == State.menu && event.to != State.menu)){
|
||||
Time.runTask(5f, platform::updateRPC);
|
||||
@ -152,10 +156,6 @@ public class Control implements ApplicationListener, Loadable{
|
||||
|
||||
@Override
|
||||
public void loadAsync(){
|
||||
saves = new Saves();
|
||||
tutorial = new Tutorial();
|
||||
music = new MusicControl();
|
||||
|
||||
Draw.scl = 1f / Core.atlas.find("scale_marker").getWidth();
|
||||
|
||||
Core.input.setCatch(KeyCode.BACK, true);
|
||||
|
@ -108,6 +108,11 @@ public class NetServer implements ApplicationListener{
|
||||
return;
|
||||
}
|
||||
|
||||
if(admins.getPlayerLimit() > 0 && playerGroup.size() >= admins.getPlayerLimit()){
|
||||
kick(id, KickReason.playerLimit);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!admins.isWhitelisted(packet.uuid, packet.usid)){
|
||||
info.adminUsid = packet.usid;
|
||||
info.lastName = packet.name;
|
||||
|
@ -69,6 +69,20 @@ public enum Gamemode{
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
public static Gamemode bestFit(Rules rules){
|
||||
if(rules.pvp){
|
||||
return pvp;
|
||||
}else if(rules.editor){
|
||||
return editor;
|
||||
}else if(rules.attackMode){
|
||||
return attack;
|
||||
}else if(rules.infiniteResources){
|
||||
return sandbox;
|
||||
}else{
|
||||
return survival;
|
||||
}
|
||||
}
|
||||
|
||||
/** Applies this preset to this ruleset. */
|
||||
public Rules apply(Rules in){
|
||||
rules.accept(in);
|
||||
|
@ -266,6 +266,10 @@ public class Saves{
|
||||
return meta == null || meta.rules == null ? null : meta.rules.zone;
|
||||
}
|
||||
|
||||
public Gamemode mode(){
|
||||
return Gamemode.bestFit(meta.rules);
|
||||
}
|
||||
|
||||
public int getBuild(){
|
||||
return meta.build;
|
||||
}
|
||||
|
@ -59,7 +59,8 @@ public abstract class InputHandler implements InputProcessor{
|
||||
|
||||
@Remote(targets = Loc.both, forward = true, called = Loc.server)
|
||||
public static void transferInventory(Player player, Tile tile){
|
||||
if(Net.server() && (player.item().amount <= 0 || player.isTransferring || !player.timer.get(Player.timerTransfer, 40))){
|
||||
if(!player.timer.get(Player.timerTransfer, 40)) return;
|
||||
if(Net.server() && (player.item().amount <= 0 || player.isTransferring)){
|
||||
throw new ValidateException(player, "Player cannot transfer an item.");
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ public class Maps{
|
||||
FileHandle dest = findFile();
|
||||
file.copyTo(dest);
|
||||
|
||||
createNewPreview(loadMap(dest, true), true);
|
||||
createNewPreview(loadMap(dest, true));
|
||||
}
|
||||
|
||||
/** Attempts to run the following code;
|
||||
@ -341,7 +341,7 @@ public class Maps{
|
||||
private void createAllPreviews(){
|
||||
Core.app.post(() -> {
|
||||
for(Map map : previewList){
|
||||
createNewPreview(map, false);
|
||||
createNewPreview(map);
|
||||
}
|
||||
previewList.clear();
|
||||
});
|
||||
@ -351,16 +351,12 @@ public class Maps{
|
||||
Core.app.post(() -> previewList.add(map));
|
||||
}
|
||||
|
||||
private void createNewPreview(Map map, boolean immediate){
|
||||
private void createNewPreview(Map map){
|
||||
try{
|
||||
//if it's here, then the preview failed to load or doesn't exist, make it
|
||||
//this has to be done synchronously!
|
||||
Pixmap pix = MapIO.generatePreview(map);
|
||||
if(immediate){
|
||||
map.texture = new Texture(pix);
|
||||
}else{
|
||||
Core.app.post(() -> map.texture = new Texture(pix));
|
||||
}
|
||||
map.texture = new Texture(pix);
|
||||
executor.submit(() -> {
|
||||
try{
|
||||
map.previewFile().writePNG(pix);
|
||||
|
@ -21,9 +21,16 @@ public class Administration{
|
||||
load();
|
||||
}
|
||||
|
||||
public int getPlayerLimit(){
|
||||
return Core.settings.getInt("playerlimit", 0);
|
||||
}
|
||||
|
||||
public void setPlayerLimit(int limit){
|
||||
Core.settings.putSave("playerlimit", limit);
|
||||
}
|
||||
|
||||
public void setStrict(boolean on){
|
||||
Core.settings.put("strict", on);
|
||||
Core.settings.save();
|
||||
Core.settings.putSave("strict", on);
|
||||
}
|
||||
|
||||
public boolean getStrict(){
|
||||
|
@ -1,15 +1,18 @@
|
||||
package io.anuke.mindustry.net;
|
||||
|
||||
import io.anuke.mindustry.game.*;
|
||||
|
||||
public class Host{
|
||||
public final String name;
|
||||
public final String address;
|
||||
public final String mapname;
|
||||
public final int wave;
|
||||
public final int players;
|
||||
public final int players, playerLimit;
|
||||
public final int version;
|
||||
public final String versionType;
|
||||
public final Gamemode mode;
|
||||
|
||||
public Host(String name, String address, String mapname, int wave, int players, int version, String versionType){
|
||||
public Host(String name, String address, String mapname, int wave, int players, int version, String versionType, Gamemode mode, int playerLimit){
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
this.players = players;
|
||||
@ -17,5 +20,7 @@ public class Host{
|
||||
this.wave = wave;
|
||||
this.version = version;
|
||||
this.versionType = versionType;
|
||||
this.playerLimit = playerLimit;
|
||||
this.mode = mode;
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,15 @@
|
||||
package io.anuke.mindustry.net;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.mindustry.entities.Entities;
|
||||
import io.anuke.mindustry.entities.type.Player;
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.io.JsonIO;
|
||||
import io.anuke.mindustry.io.SaveIO;
|
||||
import io.anuke.mindustry.io.*;
|
||||
import io.anuke.mindustry.maps.Map;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.nio.*;
|
||||
import java.util.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@ -71,8 +69,9 @@ public class NetworkIO{
|
||||
buffer.putInt(state.wave);
|
||||
buffer.putInt(Version.build);
|
||||
writeString(buffer, Version.type);
|
||||
//TODO additional information:
|
||||
// - gamemode ID/name (just pick the closest one?)
|
||||
|
||||
buffer.put((byte)Gamemode.bestFit(state.rules).ordinal());
|
||||
buffer.putInt(netServer.admins.getPlayerLimit());
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -83,13 +82,15 @@ public class NetworkIO{
|
||||
int wave = buffer.getInt();
|
||||
int version = buffer.getInt();
|
||||
String vertype = readString(buffer);
|
||||
Gamemode gamemode = Gamemode.all[buffer.get()];
|
||||
int limit = buffer.getInt();
|
||||
|
||||
return new Host(host, hostAddress, map, wave, players, version, vertype);
|
||||
return new Host(host, hostAddress, map, wave, players, version, vertype, gamemode, limit);
|
||||
}
|
||||
|
||||
private static void writeString(ByteBuffer buffer, String string, int maxlen){
|
||||
byte[] bytes = string.getBytes(charset);
|
||||
//truncating this way may lead to wierd encoding errors at the ends of strings...
|
||||
//todo truncating this way may lead to wierd encoding errors at the ends of strings...
|
||||
if(bytes.length > maxlen){
|
||||
bytes = Arrays.copyOfRange(bytes, 0, maxlen);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ public class Packets{
|
||||
|
||||
public enum KickReason{
|
||||
kick, clientOutdated, serverOutdated, banned, gameover(true), recentKick,
|
||||
nameInUse, idInUse, nameEmpty, customClient, serverClose, vote, typeMismatch, whitelist;
|
||||
nameInUse, idInUse, nameEmpty, customClient, serverClose, vote, typeMismatch, whitelist, playerLimit;
|
||||
|
||||
public final boolean quiet;
|
||||
|
||||
|
@ -197,9 +197,9 @@ public class JoinDialog extends FloatingDialog{
|
||||
server.content.table(t -> {
|
||||
t.add("[lightgray]" + host.name + " " + versionString).width(targetWidth() - 10f).left().get().setEllipsis(true);
|
||||
t.row();
|
||||
t.add("[lightgray]" + (host.players != 1 ? Core.bundle.format("players", host.players == 0 ? host.players : "[accent]" + host.players + "[lightgray]") : Core.bundle.format("players.single", "[accent]" + host.players + "[lightgray]"))).left();
|
||||
t.add("[lightgray]" + (Core.bundle.format("players" + (host.players == 1 ? ".single" : ""), (host.players == 0 ? "[lightgray]" : "[accent]") + host.players + (host.playerLimit > 0 ? "[lightgray]/[accent]" + host.playerLimit : "")+ "[lightgray]"))).left();
|
||||
t.row();
|
||||
t.add("[lightgray]" + Core.bundle.format("save.map", host.mapname) + "[lightgray] / " + Core.bundle.format("save.wave", host.wave)).width(targetWidth() - 10f).left().get().setEllipsis(true);
|
||||
t.add("[lightgray]" + Core.bundle.format("save.map", host.mapname) + "[lightgray] / " + host.mode.toString()).width(targetWidth() - 10f).left().get().setEllipsis(true);
|
||||
}).expand().left().bottom().padLeft(12f).padBottom(8);
|
||||
}
|
||||
|
||||
|
@ -137,13 +137,13 @@ public class LoadDialog extends FloatingDialog{
|
||||
meta.row();
|
||||
meta.labelWrap(Core.bundle.format("save.map", color + (slot.getMap() == null ? Core.bundle.get("unknown") : slot.getMap().name())));
|
||||
meta.row();
|
||||
meta.labelWrap(Core.bundle.format("save.wave", color + slot.getWave()));
|
||||
meta.labelWrap(slot.mode().toString() + " /" + color + " " + Core.bundle.format("save.wave", color + slot.getWave()));
|
||||
meta.row();
|
||||
meta.labelWrap(() -> Core.bundle.format("save.autosave", color + Core.bundle.get(slot.isAutosave() ? "on" : "off")));
|
||||
meta.row();
|
||||
meta.labelWrap(() -> Core.bundle.format("save.playtime", color + slot.getPlayTime()));
|
||||
meta.row();
|
||||
meta.labelWrap(Core.bundle.format("save.date", color + slot.getDate()));
|
||||
meta.labelWrap(color + slot.getDate());
|
||||
meta.row();
|
||||
}).left().growX().width(250f);
|
||||
|
||||
|
@ -71,6 +71,8 @@ public class BlockInventoryFragment extends Fragment{
|
||||
}
|
||||
|
||||
public void hide(){
|
||||
if(table == null) return;
|
||||
|
||||
table.actions(Actions.scaleTo(0f, 1f, 0.06f, Interpolation.pow3Out), Actions.run(() -> {
|
||||
table.clearChildren();
|
||||
table.clearListeners();
|
||||
|
@ -401,6 +401,26 @@ public class ServerControl implements ApplicationListener{
|
||||
info("Server name is now &lc'{0}'.", arg[0]);
|
||||
});
|
||||
|
||||
handler.register("playerlimit", "[off/somenumber]", "Set the server player limit.", arg -> {
|
||||
if(arg.length == 0){
|
||||
info("Player limit is currently &lc{0}.", netServer.admins.getPlayerLimit() == 0 ? "off" : netServer.admins.getPlayerLimit());
|
||||
return;
|
||||
}
|
||||
if(arg[0].equals("off")){
|
||||
netServer.admins.setPlayerLimit(0);
|
||||
info("Player limit disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(Strings.canParsePostiveInt(arg[0]) && Strings.parseInt(arg[0]) > 0){
|
||||
int lim = Strings.parseInt(arg[0]);
|
||||
netServer.admins.setPlayerLimit(lim);
|
||||
info("Player limit is now &lc{0}.", lim);
|
||||
}else{
|
||||
err("Limit must be a number above 0.");
|
||||
}
|
||||
});
|
||||
|
||||
handler.register("whitelist", "[on/off...]", "Enable/disable whitelisting.", arg -> {
|
||||
if(arg.length == 0){
|
||||
info("Whitelist is currently &lc{0}.", netServer.admins.isWhitelistEnabled() ? "on" : "off");
|
||||
|
Loading…
Reference in New Issue
Block a user