mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-19 10:36:43 +00:00
Added functionality to archive list of saves when the game server exits.
The number of saves that will be archived can be modified using max_archive_size in config.properties. Added shutdown hook to Main.java to handle dumping of zip files. Essential functions are in ZipUtils.java.
This commit is contained in:
parent
94c1d4689c
commit
f08b5632cc
@ -1,197 +1,214 @@
|
|||||||
package net.simon987.server;
|
package net.simon987.server;
|
||||||
|
|
||||||
|
import net.simon987.server.event.GameEvent;
|
||||||
import net.simon987.server.event.GameEvent;
|
import net.simon987.server.event.GameEventDispatcher;
|
||||||
import net.simon987.server.event.GameEventDispatcher;
|
import net.simon987.server.event.TickEvent;
|
||||||
import net.simon987.server.event.TickEvent;
|
import net.simon987.server.game.GameUniverse;
|
||||||
import net.simon987.server.game.GameUniverse;
|
import net.simon987.server.game.World;
|
||||||
import net.simon987.server.game.World;
|
import net.simon987.server.logging.LogManager;
|
||||||
import net.simon987.server.logging.LogManager;
|
import net.simon987.server.plugin.PluginManager;
|
||||||
import net.simon987.server.plugin.PluginManager;
|
import net.simon987.server.plugin.ServerPlugin;
|
||||||
import net.simon987.server.plugin.ServerPlugin;
|
import net.simon987.server.user.User;
|
||||||
import net.simon987.server.user.User;
|
import net.simon987.server.webserver.SocketServer;
|
||||||
import net.simon987.server.webserver.SocketServer;
|
import org.json.simple.JSONArray;
|
||||||
import org.json.simple.JSONArray;
|
import org.json.simple.JSONObject;
|
||||||
import org.json.simple.JSONObject;
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.File;
|
import java.io.FileWriter;
|
||||||
import java.io.FileWriter;
|
import java.io.IOException;
|
||||||
import java.io.IOException;
|
import java.util.ArrayList;
|
||||||
import java.util.ArrayList;
|
|
||||||
|
public class GameServer implements Runnable {
|
||||||
public class GameServer implements Runnable {
|
|
||||||
|
public final static GameServer INSTANCE = new GameServer();
|
||||||
public final static GameServer INSTANCE = new GameServer();
|
|
||||||
|
private GameUniverse gameUniverse;
|
||||||
private GameUniverse gameUniverse;
|
private GameEventDispatcher eventDispatcher;
|
||||||
private GameEventDispatcher eventDispatcher;
|
private PluginManager pluginManager;
|
||||||
private PluginManager pluginManager;
|
|
||||||
|
private ServerConfiguration config;
|
||||||
private ServerConfiguration config;
|
|
||||||
|
private SocketServer socketServer;
|
||||||
private SocketServer socketServer;
|
|
||||||
|
private int maxExecutionTime;
|
||||||
private int maxExecutionTime;
|
|
||||||
|
public ArrayList<byte[]> saveArchive;
|
||||||
public GameServer() {
|
|
||||||
|
public int maxArchiveSize;
|
||||||
this.config = new ServerConfiguration(new File("config.properties"));
|
|
||||||
|
public GameServer() {
|
||||||
gameUniverse = new GameUniverse(config);
|
|
||||||
pluginManager = new PluginManager();
|
this.config = new ServerConfiguration(new File("config.properties"));
|
||||||
|
|
||||||
maxExecutionTime = config.getInt("user_timeout");
|
gameUniverse = new GameUniverse(config);
|
||||||
|
pluginManager = new PluginManager();
|
||||||
//Load all plugins in plugins folder, if it doesn't exist, create it
|
|
||||||
File pluginDir = new File("plugins/");
|
maxExecutionTime = config.getInt("user_timeout");
|
||||||
File[] pluginDirListing = pluginDir.listFiles();
|
|
||||||
|
// Load all plugins in plugins folder, if it doesn't exist, create it
|
||||||
if (pluginDirListing != null) {
|
File pluginDir = new File("plugins/");
|
||||||
for (File pluginFile : pluginDirListing) {
|
File[] pluginDirListing = pluginDir.listFiles();
|
||||||
|
|
||||||
if (pluginFile.getName().endsWith(".jar")) {
|
if (pluginDirListing != null) {
|
||||||
pluginManager.load(pluginFile);
|
for (File pluginFile : pluginDirListing) {
|
||||||
}
|
|
||||||
|
if (pluginFile.getName().endsWith(".jar")) {
|
||||||
}
|
pluginManager.load(pluginFile);
|
||||||
} else {
|
}
|
||||||
if (!pluginDir.mkdir()) {
|
|
||||||
LogManager.LOGGER.severe("Couldn't create plugin directory");
|
}
|
||||||
}
|
} else {
|
||||||
}
|
if (!pluginDir.mkdir()) {
|
||||||
|
LogManager.LOGGER.severe("Couldn't create plugin directory");
|
||||||
eventDispatcher = new GameEventDispatcher(pluginManager);
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
eventDispatcher = new GameEventDispatcher(pluginManager);
|
||||||
public GameUniverse getGameUniverse() {
|
|
||||||
return gameUniverse;
|
saveArchive = new ArrayList<byte[]>();
|
||||||
}
|
|
||||||
|
maxArchiveSize = config.getInt("max_archive_size");
|
||||||
public GameEventDispatcher getEventDispatcher() {
|
}
|
||||||
return eventDispatcher;
|
|
||||||
}
|
public GameUniverse getGameUniverse() {
|
||||||
|
return gameUniverse;
|
||||||
@Override
|
}
|
||||||
public void run() {
|
|
||||||
LogManager.LOGGER.info("(G) Started game loop");
|
public GameEventDispatcher getEventDispatcher() {
|
||||||
|
return eventDispatcher;
|
||||||
long startTime; //Start time of the loop
|
}
|
||||||
long uTime; //update time
|
|
||||||
long waitTime; //time to wait
|
@Override
|
||||||
|
public void run() {
|
||||||
boolean running = true;
|
LogManager.LOGGER.info("(G) Started game loop");
|
||||||
|
|
||||||
while (running) {
|
long startTime; // Start time of the loop
|
||||||
|
long uTime; // update time
|
||||||
startTime = System.currentTimeMillis();
|
long waitTime; // time to wait
|
||||||
|
|
||||||
tick();
|
boolean running = true;
|
||||||
|
|
||||||
uTime = System.currentTimeMillis() - startTime;
|
while (running) {
|
||||||
waitTime = config.getInt("tick_length") - uTime;
|
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
LogManager.LOGGER.info("Wait time : " + waitTime + "ms | Update time: " + uTime + "ms | " + (int) (((double) uTime / waitTime) * 100) + "% load");
|
|
||||||
|
tick();
|
||||||
try {
|
|
||||||
if (waitTime >= 0) {
|
uTime = System.currentTimeMillis() - startTime;
|
||||||
Thread.sleep(waitTime);
|
waitTime = config.getInt("tick_length") - uTime;
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
LogManager.LOGGER.info("Wait time : " + waitTime + "ms | Update time: " + uTime + "ms | "
|
||||||
e.printStackTrace();
|
+ (int) (((double) uTime / waitTime) * 100) + "% load");
|
||||||
}
|
|
||||||
|
try {
|
||||||
}
|
if (waitTime >= 0) {
|
||||||
|
Thread.sleep(waitTime);
|
||||||
|
}
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
private void tick() {
|
}
|
||||||
gameUniverse.incrementTime();
|
|
||||||
|
}
|
||||||
//Dispatch tick event
|
|
||||||
GameEvent event = new TickEvent(gameUniverse.getTime());
|
}
|
||||||
GameServer.INSTANCE.getEventDispatcher().dispatch(event); //Ignore cancellation
|
|
||||||
|
private void tick() {
|
||||||
|
gameUniverse.incrementTime();
|
||||||
//Process user code
|
|
||||||
ArrayList<User> users_ = gameUniverse.getUsers();
|
// Dispatch tick event
|
||||||
for (User user : users_) {
|
GameEvent event = new TickEvent(gameUniverse.getTime());
|
||||||
|
GameServer.INSTANCE.getEventDispatcher().dispatch(event); // Ignore cancellation
|
||||||
if (user.getCpu() != null) {
|
|
||||||
try {
|
// Process user code
|
||||||
|
ArrayList<User> users_ = gameUniverse.getUsers();
|
||||||
int timeout = Math.min(user.getControlledUnit().getEnergy(), maxExecutionTime);
|
for (User user : users_) {
|
||||||
|
|
||||||
user.getCpu().reset();
|
if (user.getCpu() != null) {
|
||||||
int cost = user.getCpu().execute(timeout);
|
try {
|
||||||
user.getControlledUnit().spendEnergy(cost);
|
|
||||||
|
int timeout = Math.min(user.getControlledUnit().getEnergy(), maxExecutionTime);
|
||||||
} catch (Exception e) {
|
|
||||||
LogManager.LOGGER.severe("Error executing " + user.getUsername() + "'s code");
|
user.getCpu().reset();
|
||||||
e.printStackTrace();
|
int cost = user.getCpu().execute(timeout);
|
||||||
}
|
user.getControlledUnit().spendEnergy(cost);
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
}
|
LogManager.LOGGER.severe("Error executing " + user.getUsername() + "'s code");
|
||||||
|
e.printStackTrace();
|
||||||
//Process each worlds
|
}
|
||||||
//Avoid concurrent modification
|
|
||||||
ArrayList<World> worlds = new ArrayList<>(gameUniverse.getWorlds());
|
}
|
||||||
for (World world : worlds) {
|
}
|
||||||
world.update();
|
|
||||||
}
|
// Process each worlds
|
||||||
|
// Avoid concurrent modification
|
||||||
//Save
|
ArrayList<World> worlds = new ArrayList<>(gameUniverse.getWorlds());
|
||||||
if (gameUniverse.getTime() % config.getInt("save_interval") == 0) {
|
for (World world : worlds) {
|
||||||
save(new File("save.json"));
|
world.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
socketServer.tick();
|
// Save
|
||||||
|
if (gameUniverse.getTime() % config.getInt("save_interval") == 0) {
|
||||||
LogManager.LOGGER.info("Processed " + gameUniverse.getWorlds().size() + " worlds");
|
save(new File("save.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
socketServer.tick();
|
||||||
* Save game universe to file in JSON format
|
|
||||||
*
|
LogManager.LOGGER.info("Processed " + gameUniverse.getWorlds().size() + " worlds");
|
||||||
* @param file JSON file to save
|
}
|
||||||
*/
|
|
||||||
public void save(File file) {
|
/**
|
||||||
|
* Save game universe to file in JSON format
|
||||||
try {
|
*
|
||||||
FileWriter fileWriter = new FileWriter(file);
|
* @param file
|
||||||
|
* JSON file to save
|
||||||
JSONObject universe = gameUniverse.serialise();
|
*/
|
||||||
|
public void save(File file) {
|
||||||
JSONArray plugins = new JSONArray();
|
|
||||||
|
if (new File(new File("save.json").getAbsolutePath()).exists()) {
|
||||||
for (ServerPlugin plugin : pluginManager.getPlugins()) {
|
saveArchive.add(ZipUtils.bytifyFile("save.json"));
|
||||||
plugins.add(plugin.serialise());
|
while(saveArchive.size() > maxArchiveSize) {
|
||||||
}
|
saveArchive.remove(0);
|
||||||
|
}
|
||||||
universe.put("plugins", plugins);
|
}
|
||||||
|
|
||||||
fileWriter.write(universe.toJSONString());
|
try {
|
||||||
fileWriter.close();
|
FileWriter fileWriter = new FileWriter(file);
|
||||||
|
|
||||||
LogManager.LOGGER.info("Saved to file " + file.getName());
|
JSONObject universe = gameUniverse.serialise();
|
||||||
|
|
||||||
} catch (IOException e) {
|
JSONArray plugins = new JSONArray();
|
||||||
e.printStackTrace();
|
|
||||||
}
|
for (ServerPlugin plugin : pluginManager.getPlugins()) {
|
||||||
|
plugins.add(plugin.serialise());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerConfiguration getConfig() {
|
universe.put("plugins", plugins);
|
||||||
return config;
|
|
||||||
}
|
fileWriter.write(universe.toJSONString());
|
||||||
|
fileWriter.close();
|
||||||
public PluginManager getPluginManager() {
|
|
||||||
return pluginManager;
|
LogManager.LOGGER.info("Saved to file " + file.getName());
|
||||||
}
|
|
||||||
|
} catch (IOException e) {
|
||||||
public void setSocketServer(SocketServer socketServer) {
|
e.printStackTrace();
|
||||||
this.socketServer = socketServer;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServerConfiguration getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginManager getPluginManager() {
|
||||||
|
return pluginManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSocketServer(SocketServer socketServer) {
|
||||||
|
this.socketServer = socketServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<byte[]> getSaveArchive() {
|
||||||
|
return this.saveArchive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,29 +1,41 @@
|
|||||||
package net.simon987.server;
|
package net.simon987.server;
|
||||||
|
|
||||||
import net.simon987.server.logging.LogManager;
|
import net.simon987.server.logging.LogManager;
|
||||||
import net.simon987.server.webserver.SocketServer;
|
import net.simon987.server.webserver.SocketServer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.InetSocketAddress;
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
public class Main {
|
|
||||||
public static void main(String[] args) {
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
LogManager.initialize();
|
//Writes all of the files stored in GameServer.saveArray to a zip file.
|
||||||
ServerConfiguration config = new ServerConfiguration(new File("config.properties"));
|
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
//Load
|
try {
|
||||||
GameServer.INSTANCE.getGameUniverse().load(new File("save.json"));
|
ZipUtils.writeSavesToZip(GameServer.INSTANCE.getSaveArchive());
|
||||||
|
} catch (IOException e) {
|
||||||
SocketServer socketServer = new SocketServer(new InetSocketAddress(config.getString("webSocket_host"),
|
System.out.println("Error writing saves to zip");
|
||||||
config.getInt("webSocket_port")), config);
|
e.printStackTrace();
|
||||||
|
}
|
||||||
GameServer.INSTANCE.setSocketServer(socketServer);
|
}
|
||||||
|
}, "Shutdown-thread"));
|
||||||
|
|
||||||
(new Thread(socketServer)).start();
|
LogManager.initialize();
|
||||||
(new Thread(GameServer.INSTANCE)).start();
|
ServerConfiguration config = new ServerConfiguration(new File("config.properties"));
|
||||||
}
|
|
||||||
}
|
//Load
|
||||||
|
GameServer.INSTANCE.getGameUniverse().load(new File("save.json"));
|
||||||
|
|
||||||
|
SocketServer socketServer = new SocketServer(new InetSocketAddress(config.getString("webSocket_host"),
|
||||||
|
config.getInt("webSocket_port")), config);
|
||||||
|
|
||||||
|
GameServer.INSTANCE.setSocketServer(socketServer);
|
||||||
|
|
||||||
|
|
||||||
|
(new Thread(socketServer)).start();
|
||||||
|
(new Thread(GameServer.INSTANCE)).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
91
Server/src/main/java/net/simon987/server/ZipUtils.java
Normal file
91
Server/src/main/java/net/simon987/server/ZipUtils.java
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package net.simon987.server;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
import net.simon987.server.logging.LogManager;
|
||||||
|
|
||||||
|
public class ZipUtils {
|
||||||
|
|
||||||
|
private static final int BUFFER_SIZE = 1024;
|
||||||
|
|
||||||
|
public static byte[] bytifyFile(String fileName) {
|
||||||
|
|
||||||
|
Path path = Paths.get(fileName);
|
||||||
|
byte[] bytes = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
bytes = Files.readAllBytes(path);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Failed to extract bytes from: " + fileName);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getByteArrAsString(byte[] bytes) throws UnsupportedEncodingException {
|
||||||
|
return new String(bytes, "UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeSavesToZip(ArrayList<byte[]> array) throws IOException {
|
||||||
|
|
||||||
|
int writeCount = 0;
|
||||||
|
FileOutputStream output = new FileOutputStream("archive_" + getDateTimeStamp() + ".zip");
|
||||||
|
ZipOutputStream stream = new ZipOutputStream(output);
|
||||||
|
byte[] buffer = new byte[BUFFER_SIZE];
|
||||||
|
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
|
||||||
|
|
||||||
|
while ((bais.read(buffer)) > -1) {
|
||||||
|
for (int i = 0; i < array.size(); i++) {
|
||||||
|
|
||||||
|
ZipEntry entry = new ZipEntry("save_" + getTickTime(array.get(i)) + ".json");
|
||||||
|
stream.putNextEntry(entry);
|
||||||
|
stream.write(array.get(i));
|
||||||
|
stream.closeEntry();
|
||||||
|
writeCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.close();
|
||||||
|
output.close();
|
||||||
|
|
||||||
|
LogManager.LOGGER.info(writeCount + " saves moved to zip file archive");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getTickTime(byte[] bytes) throws UnsupportedEncodingException {
|
||||||
|
|
||||||
|
Pattern pattern = Pattern.compile("\"time\"");
|
||||||
|
String stringedBytes = getByteArrAsString(bytes);
|
||||||
|
Matcher matcher = pattern.matcher(stringedBytes);
|
||||||
|
int startIndex = 0;
|
||||||
|
|
||||||
|
while (matcher.find()) {
|
||||||
|
startIndex = matcher.end() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int endIndex = stringedBytes.indexOf(",", startIndex);
|
||||||
|
|
||||||
|
return stringedBytes.substring(startIndex, endIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getDateTimeStamp() {
|
||||||
|
Date millisToDate = new Date(System.currentTimeMillis());
|
||||||
|
SimpleDateFormat f = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||||
|
return f.format(millisToDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,65 +1,68 @@
|
|||||||
# MySQL username
|
# MySQL username
|
||||||
mysql_user=mar
|
mysql_user=mar
|
||||||
# MySQL password/
|
# MySQL password/
|
||||||
mysql_pass=mar
|
mysql_pass=mar
|
||||||
# MySQL address
|
# MySQL address
|
||||||
mysql_url=jdbc:mysql://localhost:3306/mar?useSSL=false
|
mysql_url=jdbc:mysql://localhost:3306/mar?useSSL=false
|
||||||
save_interval=10
|
save_interval=10
|
||||||
# Web server port
|
# Web server port
|
||||||
webSocket_port=8887
|
webSocket_port=8887
|
||||||
webSocket_host=0.0.0.0
|
webSocket_host=0.0.0.0
|
||||||
|
|
||||||
use_secure_webSocket=0
|
use_secure_webSocket=0
|
||||||
cert_path=certificates
|
cert_path=certificates
|
||||||
# ----------------------------------------------
|
# ----------------------------------------------
|
||||||
|
|
||||||
# Length of a tick in ms
|
# Length of a tick in ms
|
||||||
tick_length=1000
|
tick_length=1000
|
||||||
# Default offset of the origin (starting point of code execution) in words
|
# Default offset of the origin (starting point of code execution) in words
|
||||||
org_offset=1024
|
org_offset=1024
|
||||||
# Address of the stack bottom
|
# Address of the stack bottom
|
||||||
stack_bottom=32768
|
stack_bottom=32768
|
||||||
# Size of the memory in bytes
|
# Size of the memory in bytes
|
||||||
memory_size=65536
|
memory_size=65536
|
||||||
# Initial location of new user's controlled unit
|
# Initial location of new user's controlled unit
|
||||||
new_user_worldX = 32767
|
new_user_worldX = 32767
|
||||||
new_user_worldY = 32767
|
new_user_worldY = 32767
|
||||||
# Default user code
|
# Default user code
|
||||||
new_user_code=; Welcome to Much Assembly required!\n\
|
new_user_code=; Welcome to Much Assembly required!\n\
|
||||||
; You will find useful information on the game here: https://github.com/simon987/Much-Assembly-Required/wiki\n\
|
; You will find useful information on the game here: https://github.com/simon987/Much-Assembly-Required/wiki\n\
|
||||||
.text\n\
|
.text\n\
|
||||||
\t; Write code here\n\
|
\t; Write code here\n\
|
||||||
\tbrk
|
\tbrk
|
||||||
# Default held item
|
# Default held item
|
||||||
new_user_item=0
|
new_user_item=0
|
||||||
# ----------------------------------------------
|
# ----------------------------------------------
|
||||||
# Biomass units yield for a plant
|
# Biomass units yield for a plant
|
||||||
plant_yield=2
|
plant_yield=2
|
||||||
# Grow time in ticks for a plant to grow
|
# Grow time in ticks for a plant to grow
|
||||||
plant_grow_time=32
|
plant_grow_time=32
|
||||||
# Minimum tree count for the WorldGenerator
|
# Minimum tree count for the WorldGenerator
|
||||||
minTreeCount=3
|
minTreeCount=3
|
||||||
# Maximum tree count for the WorldGenerator
|
# Maximum tree count for the WorldGenerator
|
||||||
maxTreeCount=10
|
maxTreeCount=10
|
||||||
# Maximum energy of the battery hardware in kJ
|
# Maximum energy of the battery hardware in kJ
|
||||||
battery_max_energy=60000
|
battery_max_energy=60000
|
||||||
# ----------------------------------------------
|
# ----------------------------------------------
|
||||||
# Minimum center point count for the WorldGenerator
|
# Minimum center point count for the WorldGenerator
|
||||||
wg_centerPointCountMin=5
|
wg_centerPointCountMin=5
|
||||||
# Maximum center point count for the WorldGenerator
|
# Maximum center point count for the WorldGenerator
|
||||||
wg_centerPointCountMax=15
|
wg_centerPointCountMax=15
|
||||||
# Wall/Plain tile ratio for the WorldGenerator
|
# Wall/Plain tile ratio for the WorldGenerator
|
||||||
wg_wallPlainRatio=4
|
wg_wallPlainRatio=4
|
||||||
# Minimum iron tiles count for the WorldGenerator
|
# Minimum iron tiles count for the WorldGenerator
|
||||||
wg_minIronCount=0
|
wg_minIronCount=0
|
||||||
# Minimum iron tile count for the WorldGenerator
|
# Minimum iron tile count for the WorldGenerator
|
||||||
wg_maxIronCount=2
|
wg_maxIronCount=2
|
||||||
# Minimum copper tile count for the WorldGenerator
|
# Minimum copper tile count for the WorldGenerator
|
||||||
wg_minCopperCount=0
|
wg_minCopperCount=0
|
||||||
# Maximum copper tile count for the WorldGenerator
|
# Maximum copper tile count for the WorldGenerator
|
||||||
wg_maxCopperCount=2
|
wg_maxCopperCount=2
|
||||||
# ----------------------------------------------
|
# ----------------------------------------------
|
||||||
# Maximum execution time of user code in ms
|
# Maximum execution time of user code in ms
|
||||||
user_timeout=500
|
user_timeout=500
|
||||||
# Free CPU execution time in ms
|
# Free CPU execution time in ms
|
||||||
user_free_execution_time=2
|
user_free_execution_time=2
|
||||||
|
# ----------------------------------------------
|
||||||
|
# Max saves to archive when the server is shutdown
|
||||||
|
max_archive_size=10
|
Loading…
x
Reference in New Issue
Block a user