mirror of
https://bitbucket.org/projectswg/pswgcommon.git
synced 2026-01-16 23:04:32 -05:00
Updated jlcommon (removed networking code) and added mongodb data saving optionally
This commit is contained in:
@@ -18,7 +18,8 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile group: 'me.joshlarson', name: 'jlcommon', version: '1.8.4'
|
||||
compile group: 'me.joshlarson', name: 'jlcommon', version: '1.9.0'
|
||||
compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.60'
|
||||
compileOnly group: 'org.mongodb', name: 'mongodb-driver-sync', version: '3.9.1'
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,356 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.common.data.encodables.mongo;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class MongoData {
|
||||
|
||||
private final @NotNull Document doc;
|
||||
|
||||
public MongoData() {
|
||||
this(new Document());
|
||||
}
|
||||
|
||||
public MongoData(Document doc) {
|
||||
this.doc = doc == null ? new Document() : doc;
|
||||
}
|
||||
|
||||
public Document toDocument() {
|
||||
return new Document(doc);
|
||||
}
|
||||
|
||||
public boolean containsKey(String key) {
|
||||
return doc.containsKey(key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getInteger(String key) {
|
||||
return doc.getInteger(key);
|
||||
}
|
||||
|
||||
public int getInteger(String key, int defaultValue) {
|
||||
return doc.getInteger(key, defaultValue);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getLong(String key) {
|
||||
return doc.getLong(key);
|
||||
}
|
||||
|
||||
public long getLong(String key, long defaultValue) {
|
||||
Long l = doc.getLong(key);
|
||||
return l == null ? defaultValue : l;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Float getFloat(String key) {
|
||||
Double f = doc.getDouble(key);
|
||||
return f == null ? null : f.floatValue();
|
||||
}
|
||||
|
||||
public float getFloat(String key, float defaultValue) {
|
||||
Double f = doc.getDouble(key);
|
||||
return f == null ? defaultValue : f.floatValue();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Double getDouble(String key) {
|
||||
return doc.getDouble(key);
|
||||
}
|
||||
|
||||
public double getDouble(String key, double defaultValue) {
|
||||
Double d = doc.getDouble(key);
|
||||
return d == null ? defaultValue : d;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getString(String key) {
|
||||
return doc.getString(key);
|
||||
}
|
||||
|
||||
public String getString(String key, String defaultValue) {
|
||||
String str = doc.getString(key);
|
||||
return str == null ? defaultValue : str;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Boolean getBoolean(String key) {
|
||||
return doc.getBoolean(key);
|
||||
}
|
||||
|
||||
public boolean getBoolean(String key, boolean defaultValue) {
|
||||
return doc.getBoolean(key, defaultValue);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ObjectId getObjectId(String key) {
|
||||
return doc.getObjectId(key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Instant getDate(String key) {
|
||||
@SuppressWarnings("UseOfObsoleteDateTimeApi") // forced to by MongoDB
|
||||
Date d = doc.getDate(key);
|
||||
return d == null ? null : d.toInstant();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <T> List<T> getArray(String key, Class<T> klass) {
|
||||
List<?> mdbArray = doc.get(key, List.class);
|
||||
List<T> ret = new ArrayList<>(mdbArray.size());
|
||||
if (klass == Instant.class) {
|
||||
for (Object o : mdbArray) {
|
||||
if (o == null)
|
||||
ret.add(null);
|
||||
else
|
||||
//noinspection UseOfObsoleteDateTimeApi
|
||||
ret.add(klass.cast(((Date) o).toInstant()));
|
||||
}
|
||||
} else {
|
||||
for (Object o : mdbArray) {
|
||||
if (o == null)
|
||||
ret.add(null);
|
||||
else
|
||||
ret.add(klass.cast(o));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MongoData getDocument(String key) {
|
||||
return new MongoData(doc.get(key, Document.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to parse the document at the specified key. If the document exists, it will be parsed by the specified data instance.
|
||||
* @param key the key to look up
|
||||
* @param dataInstance the data instance to use
|
||||
* @param <T> the parser type
|
||||
* @return the parsed data, or null if the value does not exist
|
||||
*/
|
||||
@Nullable
|
||||
public <T extends MongoPersistable> T getDocument(String key, T dataInstance) {
|
||||
Document doc = this.doc.get(key, Document.class);
|
||||
if (doc != null)
|
||||
dataInstance.read(new MongoData(doc));
|
||||
return dataInstance;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <T> Map<String, T> getMap(String key, Class<T> klass) {
|
||||
Document mdbMap = doc.get(key, Document.class);
|
||||
Map<String, T> ret = new HashMap<>(mdbMap.size());
|
||||
if (klass == Instant.class) {
|
||||
for (Entry<String, Object> e : mdbMap.entrySet()) {
|
||||
Object o = e.getValue();
|
||||
if (o == null)
|
||||
ret.put(e.getKey(), null);
|
||||
else
|
||||
//noinspection UseOfObsoleteDateTimeApi
|
||||
ret.put(e.getKey(), klass.cast(((Date) o).toInstant()));
|
||||
}
|
||||
} else {
|
||||
for (Entry<String, Object> e : mdbMap.entrySet()) {
|
||||
Object o = e.getValue();
|
||||
if (o == null)
|
||||
ret.put(e.getKey(), null);
|
||||
else
|
||||
ret.put(e.getKey(), klass.cast(o));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void putInteger(String key, int i) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, i);
|
||||
}
|
||||
|
||||
public void putLong(String key, long l) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, l);
|
||||
}
|
||||
|
||||
public void putFloat(String key, float f) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, f);
|
||||
}
|
||||
|
||||
public void putDouble(String key, double d) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, d);
|
||||
}
|
||||
|
||||
public void putString(String key, String str) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, str);
|
||||
}
|
||||
|
||||
public void putBoolean(String key, boolean bool) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, bool);
|
||||
}
|
||||
|
||||
public void putObjectId(String key, ObjectId id) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, id);
|
||||
}
|
||||
|
||||
public void putDate(String key, Instant date) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, Date.from(date));
|
||||
}
|
||||
|
||||
public void putArray(String key, byte [] array) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
List<Integer> mdbArray = new ArrayList<>(array.length);
|
||||
for (byte b : array)
|
||||
mdbArray.add((int) b);
|
||||
doc.put(key, mdbArray);
|
||||
}
|
||||
|
||||
public void putArray(String key, short [] array) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
List<Integer> mdbArray = new ArrayList<>(array.length);
|
||||
for (short s : array)
|
||||
mdbArray.add((int) s);
|
||||
doc.put(key, mdbArray);
|
||||
}
|
||||
|
||||
public void putArray(String key, int [] array) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, List.of(array));
|
||||
}
|
||||
|
||||
public void putArray(String key, long [] array) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, List.of(array));
|
||||
}
|
||||
|
||||
public void putArray(String key, String [] array) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, List.of(array));
|
||||
}
|
||||
|
||||
public void putArray(String key, ObjectId [] array) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
doc.put(key, List.of(array));
|
||||
}
|
||||
|
||||
public void putArray(String key, Instant [] array) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
@SuppressWarnings("UseOfObsoleteDateTimeApi") // forced to by MongoDB
|
||||
List<Date> mdbArray = new ArrayList<>(array.length);
|
||||
for (Instant i : array)
|
||||
mdbArray.add(Date.from(i));
|
||||
doc.put(key, mdbArray);
|
||||
}
|
||||
|
||||
public void putArray(String key, List<?> array) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
List<Object> mdbArray = new ArrayList<>(array.size());
|
||||
for (Object o : array) {
|
||||
mdbArray.add(translatePut(o));
|
||||
}
|
||||
doc.put(key, mdbArray);
|
||||
}
|
||||
|
||||
public <T> void putArray(String key, List<T> array, Function<T, ?> converter) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
List<Object> mdbArray = new ArrayList<>(array.size());
|
||||
for (T o : array) {
|
||||
mdbArray.add(translatePut(converter.apply(o)));
|
||||
}
|
||||
doc.put(key, mdbArray);
|
||||
}
|
||||
|
||||
public void putDocument(String key, @NotNull MongoData doc) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
this.doc.put(key, doc.doc);
|
||||
}
|
||||
|
||||
public <T extends MongoPersistable> void putDocument(String key, T data) {
|
||||
assert !containsKey(key) : "key already exists";
|
||||
if (data != null) {
|
||||
MongoData dataDoc = new MongoData();
|
||||
data.save(dataDoc);
|
||||
doc.put(key, dataDoc.doc);
|
||||
}
|
||||
}
|
||||
|
||||
public void putMap(String key, Map<String, ?> data) {
|
||||
MongoData doc = new MongoData();
|
||||
for (Entry<String, ?> e : data.entrySet()) {
|
||||
doc.doc.put(e.getKey(), translatePut(e.getValue()));
|
||||
}
|
||||
putDocument(key, doc);
|
||||
}
|
||||
|
||||
public <T, S> void putMap(String key, Map<T, S> data, Function<T, String> keyExtractor) {
|
||||
MongoData doc = new MongoData();
|
||||
for (Entry<T, S> e : data.entrySet()) {
|
||||
doc.doc.put(keyExtractor.apply(e.getKey()), translatePut(e.getValue()));
|
||||
}
|
||||
putDocument(key, doc);
|
||||
}
|
||||
|
||||
public <T, S> void putMap(String key, Map<T, S> data, Function<T, String> keyExtractor, BiFunction<T, S, ?> valueExtractor) {
|
||||
MongoData doc = new MongoData();
|
||||
for (Entry<T, S> e : data.entrySet()) {
|
||||
doc.doc.put(keyExtractor.apply(e.getKey()), translatePut(valueExtractor.apply(e.getKey(), e.getValue())));
|
||||
}
|
||||
putDocument(key, doc);
|
||||
}
|
||||
|
||||
@SuppressWarnings("UseOfObsoleteDateTimeApi")
|
||||
private Object translatePut(Object input) {
|
||||
if (input instanceof Instant) {
|
||||
return Date.from((Instant) input);
|
||||
} else if (input instanceof String || input instanceof Boolean || input instanceof Long || input instanceof Date || input instanceof Document) {
|
||||
return input;
|
||||
} else if (input instanceof Float || input instanceof Double) {
|
||||
return ((Number) input).doubleValue();
|
||||
} else if (input instanceof Number) {
|
||||
return ((Number) input).intValue();
|
||||
} else
|
||||
assert false : "bad object type: " + input;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.common.data.encodables.mongo;
|
||||
|
||||
public interface MongoPersistable {
|
||||
|
||||
void read(MongoData data);
|
||||
void save(MongoData data);
|
||||
|
||||
}
|
||||
@@ -26,12 +26,14 @@
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.data.encodables.oob;
|
||||
|
||||
import com.projectswg.common.data.encodables.mongo.MongoData;
|
||||
import com.projectswg.common.data.encodables.mongo.MongoPersistable;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
import com.projectswg.common.network.NetBuffer;
|
||||
import com.projectswg.common.network.NetBufferStream;
|
||||
import com.projectswg.common.persistable.Persistable;
|
||||
|
||||
public class StringId implements OutOfBandData, Persistable {
|
||||
public class StringId implements OutOfBandData, Persistable, MongoPersistable {
|
||||
|
||||
private String key;
|
||||
private String file;
|
||||
@@ -94,6 +96,18 @@ public class StringId implements OutOfBandData, Persistable {
|
||||
key = stream.getAscii();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(MongoData data) {
|
||||
file = data.getString("file");
|
||||
key = data.getString("key");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(MongoData data) {
|
||||
data.putString("file", file);
|
||||
data.putString("key", key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutOfBandPackage.Type getOobType() {
|
||||
return OutOfBandPackage.Type.STRING_ID;
|
||||
|
||||
@@ -26,12 +26,14 @@
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.data.location;
|
||||
|
||||
import com.projectswg.common.data.encodables.mongo.MongoData;
|
||||
import com.projectswg.common.data.encodables.mongo.MongoPersistable;
|
||||
import com.projectswg.common.encoding.Encodable;
|
||||
import com.projectswg.common.network.NetBuffer;
|
||||
import com.projectswg.common.network.NetBufferStream;
|
||||
import com.projectswg.common.persistable.Persistable;
|
||||
|
||||
public class Location implements Encodable, Persistable {
|
||||
public class Location implements Encodable, Persistable, MongoPersistable {
|
||||
|
||||
private static final Location ZERO = new Location(0, 0, 0, Terrain.GONE);
|
||||
|
||||
@@ -243,6 +245,21 @@ public class Location implements Encodable, Persistable {
|
||||
terrain = Terrain.valueOf(stream.getAscii());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(MongoData data) {
|
||||
data.getDocument("orientation", orientation);
|
||||
data.getDocument("point", point);
|
||||
terrain = data.containsKey("terrain") ? Terrain.valueOf(data.getString("terrain")) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(MongoData data) {
|
||||
data.putDocument("orientation", orientation);
|
||||
data.putDocument("point", point);
|
||||
if (terrain != null)
|
||||
data.putString("terrain", terrain.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Location[TRN=%s, %s %s]", terrain, point, orientation);
|
||||
|
||||
@@ -26,12 +26,14 @@
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.data.location;
|
||||
|
||||
import com.projectswg.common.data.encodables.mongo.MongoData;
|
||||
import com.projectswg.common.data.encodables.mongo.MongoPersistable;
|
||||
import com.projectswg.common.encoding.Encodable;
|
||||
import com.projectswg.common.network.NetBuffer;
|
||||
import com.projectswg.common.network.NetBufferStream;
|
||||
import com.projectswg.common.persistable.Persistable;
|
||||
|
||||
public class Point3D implements Encodable, Persistable {
|
||||
public class Point3D implements Encodable, Persistable, MongoPersistable {
|
||||
|
||||
private double x;
|
||||
private double y;
|
||||
@@ -202,7 +204,21 @@ public class Point3D implements Encodable, Persistable {
|
||||
y = stream.getFloat();
|
||||
z = stream.getFloat();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void read(MongoData data) {
|
||||
x = data.getDouble("x", 0);
|
||||
y = data.getDouble("y", 0);
|
||||
z = data.getDouble("z", 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(MongoData data) {
|
||||
data.putDouble("x", x);
|
||||
data.putDouble("y", y);
|
||||
data.putDouble("z", z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Point3D))
|
||||
|
||||
@@ -26,13 +26,15 @@
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.data.location;
|
||||
|
||||
import com.projectswg.common.data.encodables.mongo.MongoData;
|
||||
import com.projectswg.common.data.encodables.mongo.MongoPersistable;
|
||||
import com.projectswg.common.encoding.Encodable;
|
||||
import com.projectswg.common.network.NetBuffer;
|
||||
import com.projectswg.common.network.NetBufferStream;
|
||||
import com.projectswg.common.persistable.Persistable;
|
||||
import me.joshlarson.jlcommon.utilities.Arguments;
|
||||
|
||||
public class Quaternion implements Encodable, Persistable {
|
||||
public class Quaternion implements Encodable, Persistable, MongoPersistable {
|
||||
|
||||
private final double [][] rotationMatrix;
|
||||
private double x;
|
||||
@@ -236,7 +238,23 @@ public class Quaternion implements Encodable, Persistable {
|
||||
w = stream.getFloat();
|
||||
updateRotationMatrix();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void read(MongoData data) {
|
||||
x = data.getDouble("x", 0);
|
||||
y = data.getDouble("y", 0);
|
||||
z = data.getDouble("z", 0);
|
||||
w = data.getDouble("w", 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(MongoData data) {
|
||||
data.putDouble("x", x);
|
||||
data.putDouble("y", y);
|
||||
data.putDouble("z", z);
|
||||
data.putDouble("w", w);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Quaternion[%.3f, %.3f, %.3f, %.3f]", x, y, z, w);
|
||||
|
||||
@@ -2,6 +2,7 @@ module com.projectswg.common {
|
||||
requires transitive me.joshlarson.jlcommon;
|
||||
requires static java.sql;
|
||||
requires static java.desktop;
|
||||
requires static org.mongodb.bson;
|
||||
requires org.jetbrains.annotations;
|
||||
requires org.bouncycastle.provider;
|
||||
|
||||
@@ -11,6 +12,7 @@ module com.projectswg.common {
|
||||
exports com.projectswg.common.data.encodables.chat;
|
||||
exports com.projectswg.common.data.encodables.galaxy;
|
||||
exports com.projectswg.common.data.encodables.map;
|
||||
exports com.projectswg.common.data.encodables.mongo;
|
||||
exports com.projectswg.common.data.encodables.oob;
|
||||
exports com.projectswg.common.data.encodables.oob.waypoint;
|
||||
exports com.projectswg.common.data.encodables.player;
|
||||
|
||||
Reference in New Issue
Block a user