Improved overall project structure

This commit is contained in:
kuroppoi 2021-07-09 01:48:23 +02:00
parent 4eec43f55c
commit 02a8211a5f
15 changed files with 277 additions and 64 deletions

View file

@ -2,22 +2,35 @@
Brainwine is a Deepworld private server written in Java, made with user-friendliness and portability in mind.
Due to the time it will take for this project to be complete (and my inconsistent working on it), brainwine has been prematurely open-sourced
and is free for all to use. Keep in mind, though, that this server is nowhere near finished. Expect to encounter bad code, bugs and missing features!
Brainwine is currently compatible with the latest Steam and iOS versions of Deepworld.
and is free for all to use. Keep in mind, though, that this server is nowhere near finished. Expect to encounter bad code, bugs and missing features!\
Brainwine is currently compatible with the latest Steam and iOS versions of Deepworld:
- Steam: `v3.13.1`
- iOS: `v2.11.0.1`
## Setup
### Setting up your client
### Setting up the client
Before you can connect to your (or someone else's) server, you must first let Deepworld know to where it should connect.
The exact process differs per platform. You may download an installation package for your desired platform [here.](https://github.com/kuroppoi/brainwine/releases)
Before you can connect to a server, a few modifications need to be made to the Deepworld game client.\
The exact process of this differs per platform.\
You may download an installation package for your desired platform [here.](https://github.com/kuroppoi/brainwine/releases)
### Setting up the server
Setting up your own server is as easy as downloading this repository and running `gradlew build` in a command prompt.
Alternatively, you can run the provided `build.bat` file. After the build task has finished, the output jar will be located in the `build` directory.
To start the server, simply run the jar file with a simple command line such as `java -jar brainwine.jar -Xms128m -Xmx512m`.
Be aware that Java 8 or newer is required to run Brainwine.
#### Prerequisites
- Java 8 or newer
To set up the server, clone or download this repository and run `gradlew build`.
After the build process has finished, a distribution archive should have generated in `build/distributions`.
To start the server, simply extract this archive wherever you want and run the startup script for your OS.
#### Configurations
On first-time startup, configuration files will be generated which you may modify however you like:
- `api.json` Configuration file for news & API connectivity information.
- `generators.json` Configuration file for world generation rules per biome.
- `loottables.json` Configuration file for which loot may be obtained from containers.
## Contributions

View file

@ -1,14 +1,19 @@
apply plugin: 'java-library'
plugins {
id 'java'
}
repositories {
jcenter()
}
dependencies {
implementation project(':gameserver')
implementation 'com.google.guava:guava:29.0-jre'
implementation 'org.apache.logging.log4j:log4j-api:2.14.0'
implementation 'io.javalin:javalin:3.13.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.1'
implementation 'org.slf4j:slf4j-simple:1.8.0-beta4'
implementation 'org.simplejavamail:simple-java-mail:6.5.0'
implementation project(':shared')
}
jar {
archiveBaseName = 'brainwine-api'
}

View file

@ -1,43 +0,0 @@
apply plugin: 'application'
project.ext.mainClass = 'brainwine.bootstrap.Bootstrap'
project.ext.runDir = file("$rootDir/run")
project.ext.outputDir = file("$rootDir/build")
repositories {
jcenter()
}
dependencies {
implementation project(':api')
implementation project(':gameserver')
}
application {
mainClass = project.ext.mainClass
}
run {
workingDir = project.ext.runDir
}
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
archiveBaseName = 'brainwine'
manifest {
attributes 'Main-Class': project.ext.mainClass,
'Multi-Release': 'true'
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
task copyJar(type: Copy) {
from jar
into project.ext.outputDir
}
jar.finalizedBy copyJar

54
build.gradle Normal file
View file

@ -0,0 +1,54 @@
plugins {
id 'application'
}
repositories {
jcenter()
}
dependencies {
implementation 'org.apache.logging.log4j:log4j-api:2.14.0'
implementation project(':api')
implementation project(':gameserver')
}
application {
mainClass = 'brainwine.Bootstrap'
}
run {
workingDir = file('run')
}
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
archiveBaseName = 'brainwine'
manifest {
attributes 'Main-Class': application.mainClass,
'Multi-Release': 'true'
}
}
startScripts {
doLast {
windowsScript.text = windowsScript.text.replace('..', '')
unixScript.text = unixScript.text.replace('..', '')
}
}
distZip {
eachFile { file ->
if(file.path.contains('/bin/')) {
file.setPath(file.path.replace('bin/', ''))
}
}
}
distTar {
eachFile { file ->
if(file.path.contains('/bin/')) {
file.setPath(file.path.replace('bin/', ''))
}
}
}

View file

@ -1,4 +1,6 @@
apply plugin: 'java-library'
plugins {
id 'java'
}
repositories {
jcenter()
@ -6,8 +8,7 @@ repositories {
}
dependencies {
api 'org.apache.logging.log4j:log4j-api:2.14.0'
implementation 'com.google.guava:guava:29.0-jre'
implementation 'org.apache.logging.log4j:log4j-api:2.14.0'
implementation 'org.apache.logging.log4j:log4j-core:2.14.0'
implementation 'org.msgpack:msgpack:0.6.12'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.1'
@ -15,4 +16,9 @@ dependencies {
implementation 'org.reflections:reflections:0.9.12'
implementation 'io.netty:netty-all:4.1.58.Final'
implementation 'org.mindrot:jbcrypt:0.4'
implementation project(':shared')
}
jar {
archiveBaseName = 'brainwine-gameserver'
}

1
gradle.properties Normal file
View file

@ -0,0 +1 @@
org.gradle.logging.level=info

View file

@ -1 +0,0 @@
org.gradle.jvmargs=-Xms128m -Xmx512m

View file

@ -1,2 +1,2 @@
rootProject.name = 'brainwine'
include('bootstrap', 'api', 'gameserver')
include('api', 'gameserver', 'shared')

15
shared/build.gradle Normal file
View file

@ -0,0 +1,15 @@
plugins {
id 'java'
}
repositories {
jcenter()
}
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.1'
}
jar {
archiveBaseName = 'brainwine-shared'
}

View file

@ -0,0 +1,84 @@
package brainwine.shared;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.PrettyPrinter;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter.Indenter;
public class CustomPrettyPrinter implements PrettyPrinter {
public static final CustomPrettyPrinter INSTANCE = new CustomPrettyPrinter();
private static final Indenter indenter = DefaultIndenter.SYSTEM_LINEFEED_INSTANCE;
private int nesting;
private CustomPrettyPrinter() {}
@Override
public void writeRootValueSeparator(JsonGenerator gen) throws IOException {
gen.writeRaw(DefaultPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR);
}
@Override
public void writeStartObject(JsonGenerator gen) throws IOException {
gen.writeRaw('{');
nesting++;
}
@Override
public void writeEndObject(JsonGenerator gen, int nrOfEntries) throws IOException {
nesting--;
if(nrOfEntries > 0) {
indenter.writeIndentation(gen, nesting);
}
gen.writeRaw('}');
}
@Override
public void writeObjectEntrySeparator(JsonGenerator gen) throws IOException {
gen.writeRaw(',');
indenter.writeIndentation(gen, nesting);
}
@Override
public void writeObjectFieldValueSeparator(JsonGenerator gen) throws IOException {
gen.writeRaw(": ");
}
@Override
public void writeStartArray(JsonGenerator gen) throws IOException {
gen.writeRaw('[');
nesting++;
}
@Override
public void writeEndArray(JsonGenerator gen, int nrOfValues) throws IOException {
nesting--;
if(nrOfValues > 0) {
indenter.writeIndentation(gen, nesting);
}
gen.writeRaw(']');
}
@Override
public void writeArrayValueSeparator(JsonGenerator gen) throws IOException {
gen.writeRaw(',');
indenter.writeIndentation(gen, nesting);
}
@Override
public void beforeArrayValues(JsonGenerator gen) throws IOException {
indenter.writeIndentation(gen, nesting);
}
@Override
public void beforeObjectEntries(JsonGenerator gen) throws IOException {
indenter.writeIndentation(gen, nesting);
}
}

View file

@ -0,0 +1,79 @@
package brainwine.shared;
import java.io.File;
import java.io.IOException;
import java.util.List;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
public class JsonHelper {
private static final ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true)
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
private static ObjectWriter writer = mapper.writer(CustomPrettyPrinter.INSTANCE);
public static <T> T readValue(String string, Class<T> type) throws JsonMappingException, JsonProcessingException {
return mapper.readValue(string, type);
}
public static <T> T readValue(File file, Class<T> type) throws JsonParseException, JsonMappingException, IOException {
return mapper.readValue(file, type);
}
public static <T> T readValue(Object object, Class<T> type) throws JsonProcessingException {
return readValue(writeValueAsString(object), type);
}
public static <T> T readValue(String string, TypeReference<T> type) throws JsonMappingException, JsonProcessingException {
return mapper.readValue(string, type);
}
public static <T> T readValue(File file, TypeReference<T> type) throws IOException {
return mapper.readValue(file, type);
}
public static <T> T readValue(Object object, TypeReference<T> type) throws JsonProcessingException {
return readValue(writeValueAsString(object), type);
}
public static <T> T readValue(String string, Class<T> type, InjectableValues injectableValues) throws JsonMappingException, JsonProcessingException {
return mapper.readerFor(type).with(injectableValues).readValue(string);
}
public static <T> T readValue(File file, Class<T> type, InjectableValues injectableValues) throws JsonParseException, JsonMappingException, IOException {
return mapper.readerFor(type).with(injectableValues).readValue(file);
}
public static <T> T readValue(Object object, Class<T> type, InjectableValues injectableValues) throws JsonProcessingException {
return readValue(writeValueAsString(object), type, injectableValues);
}
public static <T> List<T> readList(File file, Class<T> type) throws IOException {
return mapper.readerForListOf(type).readValue(file);
}
public static void writeValue(File file, Object value) throws JsonGenerationException, JsonMappingException, IOException {
writer.writeValue(file, value);
}
public static String writeValueAsString(Object value) throws JsonProcessingException {
return writer.writeValueAsString(value);
}
public static byte[] writeValueAsBytes(Object value) throws JsonProcessingException {
return writer.writeValueAsBytes(value);
}
}

View file

@ -1,4 +1,4 @@
package brainwine.bootstrap;
package brainwine;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -30,7 +30,7 @@ public class Bootstrap {
logger.info("Bootstrapping ...");
gameServer = new GameServer();
api = new Api();
api = new Api(new DirectDataFetcher(gameServer.getPlayerManager(), gameServer.getZoneManager()));
Runtime.getRuntime().addShutdownHook(new ShutdownThread(this));
logger.info("Bootstrap complete. Type 'stop' in the console to shutdown the server.");
runTickLoop();

View file

@ -1,4 +1,4 @@
package brainwine.bootstrap;
package brainwine;
public class ShutdownThread extends Thread {