mirror of
https://bitbucket.org/projectswg/holocore.git
synced 2026-01-16 23:04:20 -05:00
Fixed the wipeObjects config; Fixed character deletion and creation checks
This commit is contained in:
@@ -38,6 +38,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PswgObjectDatabase implements PswgDatabase {
|
||||
@@ -74,8 +75,23 @@ public class PswgObjectDatabase implements PswgDatabase {
|
||||
new BulkWriteOptions().ordered(false));
|
||||
}
|
||||
|
||||
public void removeObject(long id) {
|
||||
collection.deleteOne(Filters.eq("id", id));
|
||||
public boolean removeObject(long id) {
|
||||
return collection.deleteOne(Filters.eq("id", id)).getDeletedCount() > 0;
|
||||
}
|
||||
|
||||
public int getCharacterCount(String account) {
|
||||
return (int) collection.countDocuments(Filters.eq("account", account));
|
||||
}
|
||||
|
||||
public boolean isCharacter(String firstName) {
|
||||
return collection.countDocuments(Filters.and(
|
||||
Filters.regex("template", "object/creature/player/shared_.+\\.iff"),
|
||||
Filters.regex("base3.objectName", Pattern.compile(Pattern.quote(firstName) + "( .+|$)", Pattern.CASE_INSENSITIVE))
|
||||
)) > 0;
|
||||
}
|
||||
|
||||
public long clearObjects() {
|
||||
return collection.deleteMany(Filters.exists("_id")).getDeletedCount();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
package com.projectswg.holocore.resources.support.data.server_info.mongodb;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.model.*;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import com.mongodb.client.model.IndexOptions;
|
||||
import com.mongodb.client.model.Indexes;
|
||||
import org.bson.Document;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class PswgUserDatabase implements PswgDatabase {
|
||||
|
||||
private MongoCollection<Document> collection;
|
||||
@@ -47,7 +47,6 @@ public class PswgUserDatabase implements PswgDatabase {
|
||||
public void open(MongoCollection<Document> collection) {
|
||||
this.collection = collection;
|
||||
collection.createIndex(Indexes.ascending("username"), new IndexOptions().unique(true));
|
||||
collection.createIndex(Indexes.ascending("characters.firstName"), new IndexOptions().unique(true).partialFilterExpression(Filters.type("characters.firstName", "string")));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -55,36 +54,6 @@ public class PswgUserDatabase implements PswgDatabase {
|
||||
return collection.find(Filters.eq("username", username)).map(UserMetadata::new).first();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CharacterMetadata getCharacter(long id) {
|
||||
return collection.find(Filters.eq("characters.id", id)).map(CharacterMetadata::new).first();
|
||||
}
|
||||
|
||||
public boolean isCharacter(@NotNull String firstName) {
|
||||
return collection.countDocuments(Filters.eq("characters.firstName", firstName.toLowerCase(Locale.US)), new CountOptions().limit(1)) > 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<CharacterMetadata> getCharacters(@NotNull String username) {
|
||||
return collection.aggregate(Arrays.asList(Aggregates.match(Filters.eq("username", username)), Aggregates.unwind("$characters"))).map(CharacterMetadata::new).into(new ArrayList<>());
|
||||
}
|
||||
|
||||
public boolean deleteCharacters() {
|
||||
return collection.updateMany(Filters.exists("characters"), Updates.unset("characters")).getModifiedCount() > 0;
|
||||
}
|
||||
|
||||
public boolean deleteCharacter(String username, long id) {
|
||||
return collection.updateOne(Filters.and(Filters.eq("username", username), Filters.eq("characters.id", id)), Updates.pull("characters", Filters.eq("id", id))).getModifiedCount() > 0;
|
||||
}
|
||||
|
||||
public boolean deleteCharacter(long id) {
|
||||
return collection.updateOne(Filters.eq("characters.id", id), Updates.pull("characters", Filters.eq("id", id))).getModifiedCount() > 0;
|
||||
}
|
||||
|
||||
public boolean insertCharacter(@NotNull String username, @NotNull CharacterMetadata character) {
|
||||
return collection.updateOne(Filters.eq("username", username), Updates.addToSet("characters", character.toDocument())).getModifiedCount() > 0;
|
||||
}
|
||||
|
||||
public static class UserMetadata {
|
||||
|
||||
private final String accountId;
|
||||
@@ -123,61 +92,4 @@ public class PswgUserDatabase implements PswgDatabase {
|
||||
|
||||
}
|
||||
|
||||
public static class CharacterMetadata {
|
||||
|
||||
private final long id;
|
||||
private final String firstName;
|
||||
private final String name;
|
||||
private final String race;
|
||||
private final Document detailedData;
|
||||
|
||||
public CharacterMetadata(Document doc) {
|
||||
doc = doc.get("characters", Document.class);
|
||||
this.id = doc.getLong("id");
|
||||
this.firstName = doc.getString("firstName");
|
||||
this.name = doc.getString("name");
|
||||
this.race = doc.getString("race");
|
||||
this.detailedData = doc.get("detail", Document.class);
|
||||
}
|
||||
|
||||
public CharacterMetadata(long id, String firstName, String name, String race, Document detailedData) {
|
||||
this.id = id;
|
||||
this.firstName = firstName;
|
||||
this.name = name;
|
||||
this.race = race;
|
||||
this.detailedData = detailedData;
|
||||
}
|
||||
|
||||
public Document toDocument() {
|
||||
Document doc = new Document();
|
||||
doc.put("id", id);
|
||||
doc.put("firstName", firstName);
|
||||
doc.put("name", name);
|
||||
doc.put("race", race);
|
||||
doc.put("detailedData", detailedData);
|
||||
return doc;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getRace() {
|
||||
return race;
|
||||
}
|
||||
|
||||
public Map<String, Object> getDetailedData() {
|
||||
return Collections.unmodifiableMap(detailedData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.projectswg.holocore.services.support.data;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.mongodb.PswgDatabase;
|
||||
import me.joshlarson.jlcommon.control.Service;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
|
||||
public class ServerDataService extends Service {
|
||||
|
||||
@@ -11,14 +12,11 @@ public class ServerDataService extends Service {
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
if (PswgDatabase.config().getBoolean(this, "cleanCharacterData", false))
|
||||
wipeCharacterDatabase();
|
||||
if (PswgDatabase.config().getBoolean(this, "wipeObjects", false)) {
|
||||
Log.d("Cleared %d objects", PswgDatabase.objects().clearObjects());
|
||||
}
|
||||
|
||||
return super.initialize();
|
||||
}
|
||||
|
||||
private void wipeCharacterDatabase() {
|
||||
PswgDatabase.users().deleteCharacters();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ public class LoginService extends Service {
|
||||
@IntentHandler
|
||||
private void handleDeleteCharacterIntent(DeleteCharacterIntent dci) {
|
||||
SWGObject obj = dci.getCreature();
|
||||
if (PswgDatabase.users().deleteCharacter(obj.getObjectId())) {
|
||||
if (PswgDatabase.objects().removeObject(obj.getObjectId())) {
|
||||
DestroyObjectIntent.broadcast(obj);
|
||||
Player owner = obj.getOwner();
|
||||
if (owner != null)
|
||||
@@ -161,7 +161,13 @@ public class LoginService extends Service {
|
||||
|
||||
private void handleCharDeletion(Player player, DeleteCharacterRequest request) {
|
||||
SWGObject obj = ObjectLookup.getObjectById(request.getPlayerId());
|
||||
boolean success = obj instanceof CreatureObject && PswgDatabase.users().deleteCharacter(player.getUsername(), obj.getObjectId());
|
||||
boolean success;
|
||||
if (obj instanceof CreatureObject) {
|
||||
success = PswgDatabase.objects().removeObject(obj.getObjectId());
|
||||
players.getOrDefault(player.getAccountId(), new ArrayList<>()).remove(obj);
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
player.sendPacket(new DeleteCharacterResponse(success));
|
||||
if (success) {
|
||||
DestroyObjectIntent.broadcast(obj);
|
||||
@@ -224,12 +230,12 @@ public class LoginService extends Service {
|
||||
|
||||
private void onSuccessfulLogin(UserMetadata user, Player player) {
|
||||
switch(user.getAccessLevel()) {
|
||||
default:
|
||||
case "player": player.setAccessLevel(AccessLevel.PLAYER); break;
|
||||
case "warden": player.setAccessLevel(AccessLevel.WARDEN); break;
|
||||
case "csr": player.setAccessLevel(AccessLevel.CSR); break;
|
||||
case "qa": player.setAccessLevel(AccessLevel.QA); break;
|
||||
case "dev": player.setAccessLevel(AccessLevel.DEV); break;
|
||||
default: player.setAccessLevel(AccessLevel.PLAYER); break;
|
||||
}
|
||||
player.setAccountId(user.getUsername());
|
||||
player.setPlayerState(PlayerState.LOGGED_IN);
|
||||
|
||||
@@ -94,7 +94,7 @@ public class CharacterCreationService extends Service {
|
||||
int spaceIndex = name.indexOf(' ');
|
||||
if (spaceIndex != -1)
|
||||
name = name.substring(0, spaceIndex);
|
||||
return PswgDatabase.users().isCharacter(name);
|
||||
return PswgDatabase.objects().isCharacter(name);
|
||||
}
|
||||
|
||||
private void handleRandomNameRequest(Player player, RandomNameRequest request) {
|
||||
@@ -111,7 +111,7 @@ public class CharacterCreationService extends Service {
|
||||
String name = request.getName();
|
||||
ErrorMessage err = getNameValidity(name, player.getAccessLevel() != AccessLevel.PLAYER);
|
||||
int max = PswgDatabase.config().getInt(this, "galaxyMaxCharacters", 0);
|
||||
if (max != 0 && getCharacterCount(player.getUsername()) >= max)
|
||||
if (max != 0 && getCharacterCount(player.getAccountId()) >= max)
|
||||
err = ErrorMessage.SERVER_CHARACTER_CREATION_MAX_CHARS;
|
||||
if (err == ErrorMessage.NAME_APPROVED_MODIFIED)
|
||||
name = nameFilter.cleanName(name);
|
||||
@@ -144,7 +144,7 @@ public class CharacterCreationService extends Service {
|
||||
}
|
||||
// Too many characters
|
||||
int max = PswgDatabase.config().getInt(this, "galaxyMaxCharacters", 0);
|
||||
if (max != 0 && getCharacterCount(player.getUsername()) >= max) {
|
||||
if (max != 0 && getCharacterCount(player.getAccountId()) >= max) {
|
||||
sendCharCreationFailure(player, create, ErrorMessage.SERVER_CHARACTER_CREATION_MAX_CHARS, "too many characters");
|
||||
return null;
|
||||
}
|
||||
@@ -171,6 +171,7 @@ public class CharacterCreationService extends Service {
|
||||
private void sendCharCreationFailure(Player player, ClientCreateCharacter create, ErrorMessage err, String actualReason) {
|
||||
NameFailureReason reason = NameFailureReason.NAME_SYNTAX;
|
||||
switch (err) {
|
||||
case NAME_DECLINED_INTERNAL_ERROR:
|
||||
case NAME_APPROVED:
|
||||
reason = NameFailureReason.NAME_RETRY;
|
||||
break;
|
||||
@@ -182,7 +183,6 @@ public class CharacterCreationService extends Service {
|
||||
case NAME_DECLINED_RESERVED: reason = NameFailureReason.NAME_DEV_RESERVED; break;
|
||||
case NAME_DECLINED_TOO_FAST: reason = NameFailureReason.NAME_TOO_FAST; break;
|
||||
case SERVER_CHARACTER_CREATION_MAX_CHARS: reason = NameFailureReason.TOO_MANY_CHARACTERS; break;
|
||||
case NAME_DECLINED_INTERNAL_ERROR: reason = NameFailureReason.NAME_RETRY;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -191,7 +191,7 @@ public class CharacterCreationService extends Service {
|
||||
}
|
||||
|
||||
private int getCharacterCount(String username) {
|
||||
return PswgDatabase.users().getCharacters(username).size();
|
||||
return PswgDatabase.objects().getCharacterCount(username);
|
||||
}
|
||||
|
||||
private ErrorMessage getNameValidity(String name, boolean admin) {
|
||||
|
||||
Reference in New Issue
Block a user