mirror of
https://github.com/correl/mage.git
synced 2024-11-25 03:00:11 +00:00
[app-wiring-refactor]: Define external configuration
This commit is contained in:
parent
e3733dfae7
commit
cf3dd2d94c
14 changed files with 1083 additions and 2 deletions
|
@ -56,6 +56,21 @@
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.8.6</version>
|
<version>2.8.6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<!-- to get the reference to local repository with com\googlecode\jspf\jspf-core\0.9.1\ -->
|
<!-- to get the reference to local repository with com\googlecode\jspf\jspf-core\0.9.1\ -->
|
||||||
<repositories>
|
<repositories>
|
||||||
|
@ -82,7 +97,10 @@
|
||||||
<encoding>UTF-8</encoding>
|
<encoding>UTF-8</encoding>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
<finalName>mage-common</finalName>
|
<finalName>mage-common</finalName>
|
||||||
|
|
36
Mage.Common/src/main/java/mage/utils/FluentBuilder.java
Normal file
36
Mage.Common/src/main/java/mage/utils/FluentBuilder.java
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package mage.utils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public abstract class FluentBuilder<ToBuild, RealBuilder extends FluentBuilder<ToBuild, RealBuilder>> {
|
||||||
|
|
||||||
|
final ArrayList<Consumer<RealBuilder>> buildSequence;
|
||||||
|
private final Supplier<RealBuilder> newReference;
|
||||||
|
|
||||||
|
protected FluentBuilder(Supplier<RealBuilder> newReference) {
|
||||||
|
this.buildSequence = new ArrayList<>();
|
||||||
|
this.newReference = newReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RealBuilder copy() {
|
||||||
|
final RealBuilder realBuilder = newReference.get();
|
||||||
|
realBuilder.buildSequence.addAll(buildSequence);
|
||||||
|
return realBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract ToBuild makeValue();
|
||||||
|
|
||||||
|
public RealBuilder with(Consumer<RealBuilder> consumer) {
|
||||||
|
final RealBuilder nextBuilder = this.copy();
|
||||||
|
nextBuilder.buildSequence.add(consumer);
|
||||||
|
return nextBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToBuild build() {
|
||||||
|
final RealBuilder instance = this.copy();
|
||||||
|
instance.buildSequence.forEach(c -> c.accept(instance));
|
||||||
|
return instance.makeValue();
|
||||||
|
}
|
||||||
|
}
|
123
Mage.Common/src/test/java/mage/remote/ConnectionTest.java
Normal file
123
Mage.Common/src/test/java/mage/remote/ConnectionTest.java
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
package mage.remote;
|
||||||
|
|
||||||
|
import mage.utils.FluentBuilder;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.apache.commons.lang3.RandomUtils;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class ConnectionTest {
|
||||||
|
|
||||||
|
static class ConnectionBuilder extends FluentBuilder<Connection, ConnectionBuilder> {
|
||||||
|
|
||||||
|
public int port;
|
||||||
|
public String host;
|
||||||
|
public String parameter;
|
||||||
|
|
||||||
|
private ConnectionBuilder() {
|
||||||
|
super(ConnectionBuilder::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Connection makeValue() {
|
||||||
|
final Connection result = new Connection(parameter);
|
||||||
|
result.setHost(host);
|
||||||
|
result.setPort(port);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConnectionBuilder baseBuilder() {
|
||||||
|
return new ConnectionBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestsTemplate {
|
||||||
|
final ConnectionBuilder testeeBuilder;
|
||||||
|
|
||||||
|
TestsTemplate(ConnectionBuilder testeeBuilder) {
|
||||||
|
this.testeeBuilder = testeeBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("produce the expected scheme")
|
||||||
|
void scheme() throws Exception {
|
||||||
|
final URI testee = make(testeeBuilder);
|
||||||
|
assertThat(testee.getScheme()).isEqualTo("bisocket");
|
||||||
|
}
|
||||||
|
|
||||||
|
URI make(ConnectionBuilder builder) {
|
||||||
|
try {
|
||||||
|
return new URI(builder.build().getURI());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("generate the expected port")
|
||||||
|
void port() {
|
||||||
|
final int expected = RandomUtils.nextInt(1000, 65000);
|
||||||
|
final int port = make(testeeBuilder.with(c -> c.port = expected)).getPort();
|
||||||
|
|
||||||
|
assertThat(port).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("generate the expected serialisation parameter")
|
||||||
|
void serialisation() {
|
||||||
|
final String query = make(testeeBuilder).getQuery();
|
||||||
|
|
||||||
|
assertThat(query).contains("serializationtype=jboss");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("generate the expected threadpool parameter")
|
||||||
|
void threadpool() {
|
||||||
|
final String parameter = RandomStringUtils.randomAlphanumeric(12);
|
||||||
|
final String query = make(testeeBuilder.with(c -> c.parameter = parameter)).getQuery();
|
||||||
|
|
||||||
|
assertThat(query).contains("onewayThreadPool=mage.remote.CustomThreadPool" + parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("getUri when host is localhost should")
|
||||||
|
class LocalhostTest extends TestsTemplate {
|
||||||
|
|
||||||
|
LocalhostTest() {
|
||||||
|
super(baseBuilder().with(c -> c.host = "localhost"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("generate an ipv4 as host")
|
||||||
|
void ipv4Gen() {
|
||||||
|
final String host = make(testeeBuilder).getHost();
|
||||||
|
|
||||||
|
assertThat(host).matches("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String randomHost = RandomStringUtils.randomAlphabetic(15);
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("getUri when host is not localhost should")
|
||||||
|
class StandardHostTest extends TestsTemplate {
|
||||||
|
StandardHostTest() {
|
||||||
|
super(baseBuilder().with(c -> c.host = randomHost));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("generate the selected host as host")
|
||||||
|
void hostGen() {
|
||||||
|
final String host = make(testeeBuilder).getHost();
|
||||||
|
|
||||||
|
assertThat(host).isEqualTo(randomHost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
116
Mage.Common/src/test/java/mage/utils/FluentBuilderTest.java
Normal file
116
Mage.Common/src/test/java/mage/utils/FluentBuilderTest.java
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
package mage.utils;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
||||||
|
|
||||||
|
public class FluentBuilderTest {
|
||||||
|
|
||||||
|
|
||||||
|
private ABuilder baseBuilder() {
|
||||||
|
return new ABuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("build with default parameters")
|
||||||
|
void testDefault() {
|
||||||
|
final A actual = baseBuilder().build();
|
||||||
|
|
||||||
|
verifyAB(actual, null, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyAB(A actual, String a, int b) {
|
||||||
|
assertThat(actual.getA()).isEqualTo(a);
|
||||||
|
assertThat(actual.getB()).isEqualTo(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("chain with clause and add new parameters")
|
||||||
|
void testBaseChain() {
|
||||||
|
final A actual = baseBuilder().with(a -> a.a = "hello").build();
|
||||||
|
|
||||||
|
verifyAB(actual, "hello", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("chain multiple with clauses and add new parameters")
|
||||||
|
void testMultiChain() {
|
||||||
|
final A actual = baseBuilder().with(a -> a.a = "world").with(a -> a.b = 6).build();
|
||||||
|
|
||||||
|
verifyAB(actual, "world", 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("chain multiple with clauses and override latest writes")
|
||||||
|
void testMultiChainOverride() {
|
||||||
|
final A actual = baseBuilder().with(a -> a.a = "world").with(a -> a.b = 4).with(a -> a.a = "foobar").build();
|
||||||
|
|
||||||
|
verifyAB(actual, "foobar", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("not mutate the state of previous builder in the chain")
|
||||||
|
void testImmutability() {
|
||||||
|
final ABuilder builder1 = baseBuilder().with(a -> a.a = "world");
|
||||||
|
final ABuilder builder2 = builder1.with(a -> {
|
||||||
|
a.a = "hello";
|
||||||
|
a.b = 42;
|
||||||
|
});
|
||||||
|
|
||||||
|
verifyAB(builder1.build(), "world", 0);
|
||||||
|
verifyAB(builder2.build(), "hello", 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("produce different objects")
|
||||||
|
void differentObjects() {
|
||||||
|
final ABuilder builder = baseBuilder().with(a -> {
|
||||||
|
a.a = "hello";
|
||||||
|
a.b = 42;
|
||||||
|
});
|
||||||
|
final A a1 = builder.build();
|
||||||
|
final A a2 = builder.build();
|
||||||
|
|
||||||
|
assertThat(a1).isNotSameAs(a2);
|
||||||
|
verifyAB(a1, "hello", 42);
|
||||||
|
verifyAB(a2, "hello", 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class A {
|
||||||
|
public final String a;
|
||||||
|
private int b;
|
||||||
|
|
||||||
|
public A(String a) {
|
||||||
|
this.a = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getA() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getB() {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setB(int b) {
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ABuilder extends FluentBuilder<A, ABuilder> {
|
||||||
|
public String a;
|
||||||
|
public int b;
|
||||||
|
|
||||||
|
private ABuilder() {
|
||||||
|
super(ABuilder::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected A makeValue() {
|
||||||
|
final A result = new A(a);
|
||||||
|
result.setB(b);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
173
Mage.Server/config/config_error.xml
Normal file
173
Mage.Server/config/config_error.xml
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!-- Configuration file with integers set as strings to cause unmarshalling errors -->
|
||||||
|
<config>
|
||||||
|
<server serverAddress="0.0.0.0"
|
||||||
|
serverName="mage-server"
|
||||||
|
port="NOT AN INTEGER"
|
||||||
|
secondaryBindPort="NOT AN INTEGER"
|
||||||
|
backlogSize="NOT AN INTEGER"
|
||||||
|
numAcceptThreads="NOT AN INTEGER"
|
||||||
|
maxPoolSize="NOT AN INTEGER"
|
||||||
|
leasePeriod="NOT AN INTEGER"
|
||||||
|
socketWriteTimeout="NOT AN INTEGER"
|
||||||
|
maxGameThreads="NOT AN INTEGER"
|
||||||
|
maxSecondsIdle="NOT AN INTEGER"
|
||||||
|
minUserNameLength="NOT AN INTEGER"
|
||||||
|
maxUserNameLength="NOT AN INTEGER"
|
||||||
|
invalidUserNamePattern="[^a-z0-9_]"
|
||||||
|
minPasswordLength="NOT AN INTEGER"
|
||||||
|
maxPasswordLength="NOT AN INTEGER"
|
||||||
|
maxAiOpponents="NOT AN INTEGER"
|
||||||
|
saveGameActivated="false"
|
||||||
|
authenticationActivated="false"
|
||||||
|
googleAccount=""
|
||||||
|
mailgunApiKey=""
|
||||||
|
mailgunDomain=""
|
||||||
|
mailSmtpHost=""
|
||||||
|
mailSmtpPort=""
|
||||||
|
mailUser=""
|
||||||
|
mailPassword=""
|
||||||
|
mailFromAddress=""
|
||||||
|
/>
|
||||||
|
<playerTypes>
|
||||||
|
<playerType name="Human" jar="mage-player-human.jar" className="mage.player.human.HumanPlayer"/>
|
||||||
|
<!--<playerType name="Computer - minimax" jar="mage-player-aiminimax.jar" className="mage.player.ai.ComputerPlayer3"/>-->
|
||||||
|
<playerType name="Computer - mad" jar="mage-player-ai-ma.jar" className="mage.player.ai.ComputerPlayer7"/>
|
||||||
|
<playerType name="Computer - monte carlo" jar="mage-player-aimcts.jar" className="mage.player.ai.ComputerPlayerMCTS"/>
|
||||||
|
<playerType name="Computer - draftbot" jar="mage-player-ai-draft-bot.jar" className="mage.player.ai.ComputerDraftPlayer"/>
|
||||||
|
</playerTypes>
|
||||||
|
<gameTypes>
|
||||||
|
<gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerMatch" typeName="mage.game.TwoPlayerDuelType"/>
|
||||||
|
<gameType name="Free For All" jar="mage-game-freeforall.jar" className="mage.game.FreeForAllMatch" typeName="mage.game.FreeForAllType"/>
|
||||||
|
<gameType name="Commander Two Player Duel" jar="mage-game-commanderduel.jar" className="mage.game.CommanderDuelMatch" typeName="mage.game.CommanderDuelType"/>
|
||||||
|
<gameType name="Commander Free For All" jar="mage-game-commanderfreeforall.jar" className="mage.game.CommanderFreeForAllMatch" typeName="mage.game.CommanderFreeForAllType"/>
|
||||||
|
<gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/>
|
||||||
|
<gameType name="Canadian Highlander Two Player Duel" jar="mage-game-canadianhighlanderduel.jar" className="mage.game.CanadianHighlanderDuelMatch" typeName="mage.game.CanadianHighlanderDuelType"/>
|
||||||
|
<gameType name="Penny Dreadful Commander Free For All" jar="mage-game-pennydreadfulcommanderfreeforall.jar" className="mage.game.PennyDreadfulCommanderFreeForAllMatch" typeName="mage.game.PennyDreadfulCommanderFreeForAllType"/>
|
||||||
|
<gameType name="Freeform Commander Two Player Duel" jar="mage-game-freeformcommanderduel.jar" className="mage.game.FreeformCommanderDuelMatch" typeName="mage.game.FreeformCommanderDuelType"/>
|
||||||
|
<gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/>
|
||||||
|
<gameType name="Freeform Unlimited Commander" jar="mage-game-freeformunlimitedcommander.jar" className="mage.game.FreeformUnlimitedCommanderMatch" typeName="mage.game.FreeformUnlimitedCommanderType"/>
|
||||||
|
<gameType name="Oathbreaker Two Player Duel" jar="mage-game-oathbreakerduel.jar" className="mage.game.OathbreakerDuelMatch" typeName="mage.game.OathbreakerDuelType"/>
|
||||||
|
<gameType name="Oathbreaker Free For All" jar="mage-game-oathbreakerfreeforall.jar" className="mage.game.OathbreakerFreeForAllMatch" typeName="mage.game.OathbreakerFreeForAllType"/>
|
||||||
|
<gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/>
|
||||||
|
<gameType name="Brawl Free For All" jar="mage-game-brawlfreeforall.jar" className="mage.game.BrawlFreeForAllMatch" typeName="mage.game.BrawlFreeForAllType"/>
|
||||||
|
<gameType name="Momir Basic Two Player Duel" jar="mage-game-momirduel.jar" className="mage.game.MomirDuelMatch" typeName="mage.game.MomirDuelType"/>
|
||||||
|
<gameType name="Momir Basic Free For All" jar="mage-game-momir.jar" className="mage.game.MomirFreeForAllMatch" typeName="mage.game.MomirFreeForAllType"/>
|
||||||
|
</gameTypes>
|
||||||
|
<tournamentTypes>
|
||||||
|
<tournamentType name="Constructed Elimination" jar="mage-tournament-constructed.jar" className="mage.tournament.ConstructedEliminationTournament" typeName="mage.tournament.ConstructedEliminationTournamentType"/>
|
||||||
|
<tournamentType name="Constructed Swiss" jar="mage-tournament-constructed.jar" className="mage.tournament.ConstructedSwissTournament" typeName="mage.tournament.ConstructedSwissTournamentType"/>
|
||||||
|
<tournamentType name="Booster Draft Elimination" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationTournamentType"/>
|
||||||
|
<tournamentType name="Booster Draft Elimination (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationCubeTournamentType"/>
|
||||||
|
<tournamentType name="Booster Draft Elimination (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftEliminationTournament" typeName="mage.tournament.RandomBoosterDraftEliminationTournamentType"/>
|
||||||
|
<tournamentType name="Booster Draft Elimination (Rich Man)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManDraftEliminationTournament" typeName="mage.tournament.RichManDraftEliminationTournamentType"/>
|
||||||
|
<tournamentType name="Booster Draft Elimination (Rich Man Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManCubeDraftEliminationTournament" typeName="mage.tournament.RichManCubeDraftEliminationTournamentType"/>
|
||||||
|
<tournamentType name="Booster Draft Swiss" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissTournamentType"/>
|
||||||
|
<tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/>
|
||||||
|
<tournamentType name="Booster Draft Swiss (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftSwissTournament" typeName="mage.tournament.RandomBoosterDraftSwissTournamentType"/>
|
||||||
|
<tournamentType name="Sealed Elimination" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationTournamentType"/>
|
||||||
|
<tournamentType name="Sealed Elimination (Cube)" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationCubeTournamentType"/>
|
||||||
|
<tournamentType name="Sealed Swiss" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissTournamentType"/>
|
||||||
|
<tournamentType name="Sealed Swiss (Cube)" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissCubeTournamentType"/>
|
||||||
|
<tournamentType name="Jumpstart Elimination" jar="mage-tournament-sealed.jar" className="mage.tournament.JumpstartEliminationTournament" typeName="mage.tournament.JumpstartEliminationTournamentType"/>
|
||||||
|
<tournamentType name="Jumpstart Swiss" jar="mage-tournament-sealed.jar" className="mage.tournament.JumpstartSwissTournament" typeName="mage.tournament.JumpstartSwissTournamentType"/>
|
||||||
|
</tournamentTypes>
|
||||||
|
<draftCubes>
|
||||||
|
<draftCube name="Adam Styborski's Pauper Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.AdamStyborskisPauperCube"/>
|
||||||
|
<draftCube name="Ben's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.BensCube"/>
|
||||||
|
<draftCube name="Cube Tutor 360 Pauper" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeTutor360Pauper"/>
|
||||||
|
<draftCube name="Cube Tutor 720" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeTutor720"/>
|
||||||
|
<draftCube name="Eric Klug's Pro Tour Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.EricKlugsProTourCube"/>
|
||||||
|
<draftCube name="Guillaume Matignon's Jenny's/Johnny's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.GuillaumeMatignonsJennysJohnnysCube"/>
|
||||||
|
<draftCube name="Jim Davis's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.JimDavisCube"/>
|
||||||
|
<draftCube name="Joseph Vasoli's Peasant Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.JosephVasolisPeasantCube"/>
|
||||||
|
<draftCube name="Mono Blue Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MonoBlueCube"/>
|
||||||
|
<draftCube name="Sam Black's No Search Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.SamBlacksCube"/>
|
||||||
|
<draftCube name="Timothee Simonot's Twisted Color Pie Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.TimotheeSimonotsTwistedColorPieCube"/>
|
||||||
|
<draftCube name="MTGA Cube 2020 April" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGACube2020April"/>
|
||||||
|
<draftCube name="MTGO Cube March 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGOMarchCube2014"/>
|
||||||
|
<draftCube name="MTGO Legacy Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube"/>
|
||||||
|
<draftCube name="MTGO Legacy Cube 2015 March" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeMarch2015"/>
|
||||||
|
<draftCube name="MTGO Legacy Cube 2015 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/>
|
||||||
|
<draftCube name="MTGO Legacy Cube 2016 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/>
|
||||||
|
<draftCube name="MTGO Legacy Cube 2016 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/>
|
||||||
|
<draftCube name="MTGO Legacy Cube 2017 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/>
|
||||||
|
<draftCube name="MTGO Legacy Cube 2017 April" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeApril2017"/>
|
||||||
|
<draftCube name="MTGO Legacy Cube 2018 February" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube2018February"/>
|
||||||
|
<draftCube name="MTGO Legacy Cube 2019 July" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJuly2019"/>
|
||||||
|
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCube"/>
|
||||||
|
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
|
||||||
|
<draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ModernCube2017"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2013"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2014"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube 2015" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2015"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2016"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube June 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2016"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube November 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeNovember2016"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube June 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2017"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube December 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeDecember2017"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube June 2018" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2018"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube December 2018" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeDecember2018"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube June 2019" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2019"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube December 2019" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeDecember2019"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube April 2020" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeApril2020"/>
|
||||||
|
<draftCube name="MTGO Vintage Cube July 2020" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJuly2020"/>
|
||||||
|
<draftCube name="SCG Con Cube 2018 December" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ScgConCube2018December"/>
|
||||||
|
<draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/>
|
||||||
|
<draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGCube"/>
|
||||||
|
<draftCube name="Cube From Deck" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeFromDeck"/>
|
||||||
|
</draftCubes>
|
||||||
|
<deckTypes>
|
||||||
|
<deckType name="Constructed - Standard" jar="mage-deck-constructed.jar" className="mage.deck.Standard"/>
|
||||||
|
<deckType name="Constructed - Extended" jar="mage-deck-constructed.jar" className="mage.deck.Extended"/>
|
||||||
|
<deckType name="Constructed - Frontier" jar="mage-deck-constructed.jar" className="mage.deck.Frontier"/>
|
||||||
|
<deckType name="Constructed - Pioneer" jar="mage-deck-constructed.jar" className="mage.deck.Pioneer"/>
|
||||||
|
<deckType name="Constructed - Modern" jar="mage-deck-constructed.jar" className="mage.deck.Modern"/>
|
||||||
|
<deckType name="Constructed - Modern - No Banned List" jar="mage-deck-constructed.jar" className="mage.deck.ModernNoBannedList"/>
|
||||||
|
<deckType name="Constructed - Eternal" jar="mage-deck-constructed.jar" className="mage.deck.Eternal"/>
|
||||||
|
<deckType name="Constructed - Legacy" jar="mage-deck-constructed.jar" className="mage.deck.Legacy"/>
|
||||||
|
<deckType name="Constructed - Vintage" jar="mage-deck-constructed.jar" className="mage.deck.Vintage"/>
|
||||||
|
<deckType name="Constructed - Pauper" jar="mage-deck-constructed.jar" className="mage.deck.Pauper"/>
|
||||||
|
<deckType name="Constructed - Historic" jar="mage-deck-constructed.jar" className="mage.deck.Historic"/>
|
||||||
|
<deckType name="Constructed - Historical Type 2" jar="mage-deck-constructed.jar" className="mage.deck.HistoricalType2"/>
|
||||||
|
<deckType name="Constructed - Super Type 2" jar="mage-deck-constructed.jar" className="mage.deck.SuperType2"/>
|
||||||
|
<deckType name="Constructed - Australian Highlander" jar="mage-deck-constructed.jar" className="mage.deck.AusHighlander"/>
|
||||||
|
<deckType name="Constructed - Canadian Highlander" jar="mage-deck-constructed.jar" className="mage.deck.CanadianHighlander"/>
|
||||||
|
<deckType name="Constructed - Old School 93/94" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394"/>
|
||||||
|
<deckType name="Constructed - Old School 93/94 - Italian Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394Italian"/>
|
||||||
|
<deckType name="Constructed - Old School 93/94 - Channel Fireball Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394CFB"/>
|
||||||
|
<deckType name="Constructed - Old School 93/94 - EudoGames Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EG"/>
|
||||||
|
<deckType name="Constructed - Old School 93/94 - EC Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EC"/>
|
||||||
|
<deckType name="Constructed - Premodern" jar="mage-deck-constructed.jar" className="mage.deck.Premodern"/>
|
||||||
|
<deckType name="Constructed - Freeform" jar="mage-deck-constructed.jar" className="mage.deck.Freeform"/>
|
||||||
|
<deckType name="Variant Magic - Commander" jar="mage-deck-constructed.jar" className="mage.deck.Commander"/>
|
||||||
|
<deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed.jar" className="mage.deck.DuelCommander"/>
|
||||||
|
<deckType name="Variant Magic - MTGO 1v1 Commander" jar="mage-deck-constructed.jar" className="mage.deck.MTGO1v1Commander"/>
|
||||||
|
<deckType name="Variant Magic - Centurion Commander" jar="mage-deck-constructed.jar" className="mage.deck.CenturionCommander"/>
|
||||||
|
<deckType name="Variant Magic - Tiny Leaders" jar="mage-deck-constructed.jar" className="mage.deck.TinyLeaders"/>
|
||||||
|
<deckType name="Variant Magic - Momir Basic" jar="mage-deck-constructed.jar" className="mage.deck.Momir"/>
|
||||||
|
<deckType name="Variant Magic - Penny Dreadful Commander" jar="mage-deck-constructed.jar" className="mage.deck.PennyDreadfulCommander"/>
|
||||||
|
<deckType name="Variant Magic - Freeform Commander" jar="mage-deck-constructed.jar" className="mage.deck.FreeformCommander"/>
|
||||||
|
<deckType name="Variant Magic - Freeform Unlimited Commander" jar="mage-deck-constructed.jar" className="mage.deck.FreeformUnlimitedCommander"/>
|
||||||
|
<deckType name="Variant Magic - Brawl" jar="mage-deck-constructed.jar" className="mage.deck.Brawl"/>
|
||||||
|
<deckType name="Variant Magic - Oathbreaker" jar="mage-deck-constructed.jar" className="mage.deck.Oathbreaker"/>
|
||||||
|
<deckType name="Block Constructed - Amonkhet" jar="mage-deck-constructed.jar" className="mage.deck.AmonkhetBlock"/>
|
||||||
|
<deckType name="Block Constructed - Battle for Zendikar" jar="mage-deck-constructed.jar" className="mage.deck.BattleForZendikarBlock"/>
|
||||||
|
<deckType name="Block Constructed - Innistrad" jar="mage-deck-constructed.jar" className="mage.deck.InnistradBlock"/>
|
||||||
|
<deckType name="Block Constructed - Ixalan" jar="mage-deck-constructed.jar" className="mage.deck.IxalanBlock"/>
|
||||||
|
<deckType name="Block Constructed - Kaladesh" jar="mage-deck-constructed.jar" className="mage.deck.KaladeshBlock"/>
|
||||||
|
<deckType name="Block Constructed - Kamigawa" jar="mage-deck-constructed.jar" className="mage.deck.KamigawaBlock"/>
|
||||||
|
<deckType name="Block Constructed - Khans of Tarkir" jar="mage-deck-constructed.jar" className="mage.deck.KhansOfTarkirBlock"/>
|
||||||
|
<deckType name="Block Constructed - Lorwyn" jar="mage-deck-constructed.jar" className="mage.deck.LorwynBlock"/>
|
||||||
|
<deckType name="Block Constructed - Return to Ravnica" jar="mage-deck-constructed.jar" className="mage.deck.ReturnToRavnicaBlock"/>
|
||||||
|
<deckType name="Block Constructed - Scars of Mirrodin" jar="mage-deck-constructed.jar" className="mage.deck.ScarsOfMirrodinBlock"/>
|
||||||
|
<deckType name="Block Constructed - Shadowmoor" jar="mage-deck-constructed.jar" className="mage.deck.ShadowmoorBlock"/>
|
||||||
|
<deckType name="Block Constructed - Shadows over Innistrad" jar="mage-deck-constructed.jar" className="mage.deck.ShadowsOverInnistradBlock"/>
|
||||||
|
<deckType name="Block Constructed - Shards of Alara" jar="mage-deck-constructed.jar" className="mage.deck.ShardsOfAlaraBlock"/>
|
||||||
|
<deckType name="Block Constructed - Theros" jar="mage-deck-constructed.jar" className="mage.deck.TherosBlock"/>
|
||||||
|
<deckType name="Block Constructed - Zendikar" jar="mage-deck-constructed.jar" className="mage.deck.ZendikarBlock"/>
|
||||||
|
<deckType name="Block Constructed Custom - Star Wars" jar="mage-deck-constructed.jar" className="mage.deck.StarWarsBlock"/>
|
||||||
|
<deckType name="Limited" jar="mage-deck-limited.jar" className="mage.deck.Limited"/>
|
||||||
|
</deckTypes>
|
||||||
|
</config>
|
|
@ -285,6 +285,18 @@
|
||||||
<artifactId>sqlite-jdbc</artifactId>
|
<artifactId>sqlite-jdbc</artifactId>
|
||||||
<version>3.32.3.2</version>
|
<version>3.32.3.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Test dependencies -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -358,6 +370,10 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
<finalName>mage-server</finalName>
|
<finalName>mage-server</finalName>
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package mage.server.util;
|
||||||
|
|
||||||
|
import mage.server.util.config.Config;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.Unmarshaller;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class ConfigFactory {
|
||||||
|
|
||||||
|
public static Config loadFromFile(final String filePath) {
|
||||||
|
try {
|
||||||
|
final JAXBContext jaxbContext = JAXBContext.newInstance("mage.server.util.config");
|
||||||
|
final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
|
||||||
|
return (Config) unmarshaller.unmarshal(new File(filePath));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ConfigurationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ import org.apache.log4j.Logger;
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public enum ConfigSettings {
|
public enum ConfigSettings implements ConfigSettingsContract {
|
||||||
instance;
|
instance;
|
||||||
private final Logger logger = Logger.getLogger(ConfigSettings.class);
|
private final Logger logger = Logger.getLogger(ConfigSettings.class);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package mage.server.util;
|
||||||
|
|
||||||
|
import mage.server.util.config.GamePlugin;
|
||||||
|
import mage.server.util.config.Plugin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ConfigSettingsContract {
|
||||||
|
String getServerAddress();
|
||||||
|
|
||||||
|
String getServerName();
|
||||||
|
|
||||||
|
int getPort();
|
||||||
|
|
||||||
|
int getSecondaryBindPort();
|
||||||
|
|
||||||
|
int getLeasePeriod();
|
||||||
|
|
||||||
|
int getSocketWriteTimeout();
|
||||||
|
|
||||||
|
int getMaxPoolSize();
|
||||||
|
|
||||||
|
int getNumAcceptThreads();
|
||||||
|
|
||||||
|
int getBacklogSize();
|
||||||
|
|
||||||
|
int getMaxGameThreads();
|
||||||
|
|
||||||
|
int getMaxSecondsIdle();
|
||||||
|
|
||||||
|
int getMinUserNameLength();
|
||||||
|
|
||||||
|
int getMaxUserNameLength();
|
||||||
|
|
||||||
|
String getInvalidUserNamePattern();
|
||||||
|
|
||||||
|
int getMinPasswordLength();
|
||||||
|
|
||||||
|
int getMaxPasswordLength();
|
||||||
|
|
||||||
|
String getMaxAiOpponents();
|
||||||
|
|
||||||
|
Boolean isSaveGameActivated();
|
||||||
|
|
||||||
|
Boolean isAuthenticationActivated();
|
||||||
|
|
||||||
|
String getGoogleAccount();
|
||||||
|
|
||||||
|
String getMailgunApiKey();
|
||||||
|
|
||||||
|
String getMailgunDomain();
|
||||||
|
|
||||||
|
String getMailSmtpHost();
|
||||||
|
|
||||||
|
String getMailSmtpPort();
|
||||||
|
|
||||||
|
String getMailUser();
|
||||||
|
|
||||||
|
String getMailPassword();
|
||||||
|
|
||||||
|
String getMailFromAddress();
|
||||||
|
|
||||||
|
List<Plugin> getPlayerTypes();
|
||||||
|
|
||||||
|
List<GamePlugin> getGameTypes();
|
||||||
|
|
||||||
|
List<GamePlugin> getTournamentTypes();
|
||||||
|
|
||||||
|
List<Plugin> getDraftCubes();
|
||||||
|
|
||||||
|
List<Plugin> getDeckTypes();
|
||||||
|
}
|
145
Mage.Server/src/main/java/mage/server/util/ConfigWrapper.java
Normal file
145
Mage.Server/src/main/java/mage/server/util/ConfigWrapper.java
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
package mage.server.util;
|
||||||
|
|
||||||
|
import mage.server.util.config.Config;
|
||||||
|
import mage.server.util.config.GamePlugin;
|
||||||
|
import mage.server.util.config.Plugin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ConfigWrapper implements ConfigSettingsContract {
|
||||||
|
|
||||||
|
private final Config config;
|
||||||
|
|
||||||
|
public ConfigWrapper(final Config config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerAddress() {
|
||||||
|
return config.getServer().getServerAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerName() {
|
||||||
|
return config.getServer().getServerName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return config.getServer().getPort().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSecondaryBindPort() {
|
||||||
|
return config.getServer().getSecondaryBindPort().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLeasePeriod() {
|
||||||
|
return config.getServer().getLeasePeriod().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSocketWriteTimeout() {
|
||||||
|
return config.getServer().getSocketWriteTimeout().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxPoolSize() {
|
||||||
|
return config.getServer().getMaxPoolSize().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumAcceptThreads() {
|
||||||
|
return config.getServer().getNumAcceptThreads().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBacklogSize() {
|
||||||
|
return config.getServer().getBacklogSize().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxGameThreads() {
|
||||||
|
return config.getServer().getMaxGameThreads().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxSecondsIdle() {
|
||||||
|
return config.getServer().getMaxSecondsIdle().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinUserNameLength() {
|
||||||
|
return config.getServer().getMinUserNameLength().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxUserNameLength() {
|
||||||
|
return config.getServer().getMaxUserNameLength().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInvalidUserNamePattern() {
|
||||||
|
return config.getServer().getInvalidUserNamePattern();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinPasswordLength() {
|
||||||
|
return config.getServer().getMinPasswordLength().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxPasswordLength() {
|
||||||
|
return config.getServer().getMaxPasswordLength().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMaxAiOpponents() {
|
||||||
|
return config.getServer().getMaxAiOpponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isSaveGameActivated() {
|
||||||
|
return config.getServer().isSaveGameActivated();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isAuthenticationActivated() {
|
||||||
|
return config.getServer().isAuthenticationActivated();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGoogleAccount() {
|
||||||
|
return config.getServer().getGoogleAccount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMailgunApiKey() {
|
||||||
|
return config.getServer().getMailgunApiKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMailgunDomain() {
|
||||||
|
return config.getServer().getMailgunDomain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMailSmtpHost() {
|
||||||
|
return config.getServer().getMailSmtpHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMailSmtpPort() {
|
||||||
|
return config.getServer().getMailSmtpPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMailUser() {
|
||||||
|
return config.getServer().getMailUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMailPassword() {
|
||||||
|
return config.getServer().getMailPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMailFromAddress() {
|
||||||
|
return config.getServer().getMailFromAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Plugin> getPlayerTypes() {
|
||||||
|
return config.getPlayerTypes().getPlayerType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GamePlugin> getGameTypes() {
|
||||||
|
return config.getGameTypes().getGameType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GamePlugin> getTournamentTypes() {
|
||||||
|
return config.getTournamentTypes().getTournamentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Plugin> getDraftCubes() {
|
||||||
|
return config.getDraftCubes().getDraftCube();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Plugin> getDeckTypes() {
|
||||||
|
return config.getDeckTypes().getDeckType();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package mage.server.util;
|
||||||
|
|
||||||
|
public class ConfigurationException extends RuntimeException {
|
||||||
|
public ConfigurationException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package mage.server.util;
|
||||||
|
|
||||||
|
import mage.server.util.config.Config;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
|
||||||
|
public class ConfigFactoryTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("should unmarshal configuration from file")
|
||||||
|
void loadConfig() {
|
||||||
|
final Config config = ConfigFactory.loadFromFile("config/config.xml");
|
||||||
|
|
||||||
|
assertThat(config.getServer().getServerName()).isEqualTo("mage-server");
|
||||||
|
assertThat(config.getServer().getPort()).isEqualTo(17171);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("should fail if config is malformed")
|
||||||
|
void failOnMalformed() {
|
||||||
|
assertThatExceptionOfType(ConfigurationException.class)
|
||||||
|
.isThrownBy(() -> ConfigFactory.loadFromFile("config/config_error.xml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("should fail if file does not exist")
|
||||||
|
void failOnNotFound() {
|
||||||
|
assertThatExceptionOfType(ConfigurationException.class)
|
||||||
|
.isThrownBy(() -> ConfigFactory.loadFromFile("does not exist"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,294 @@
|
||||||
|
package mage.server.util;
|
||||||
|
|
||||||
|
import mage.server.util.config.*;
|
||||||
|
import mage.utils.FluentBuilder;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.apache.commons.lang3.RandomUtils;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.DynamicTest;
|
||||||
|
import org.junit.jupiter.api.TestFactory;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class ConfigWrapperTest {
|
||||||
|
|
||||||
|
static class ConfigBuilder extends FluentBuilder<Config, ConfigBuilder> {
|
||||||
|
|
||||||
|
public String serverAddress;
|
||||||
|
public String serverName;
|
||||||
|
public int port;
|
||||||
|
public int secondaryBindPort;
|
||||||
|
public int leasePeriod;
|
||||||
|
public int socketWriteTimeout;
|
||||||
|
public int maxPoolSize;
|
||||||
|
public int numAcceptThreads;
|
||||||
|
public int backlogSize;
|
||||||
|
public int maxGameThreads;
|
||||||
|
public int maxSecondsIdle;
|
||||||
|
public int minUsernameLength;
|
||||||
|
public int maxUsernameLength;
|
||||||
|
public String invalidUsernamePattern;
|
||||||
|
public int minPasswordLength;
|
||||||
|
public int maxPasswordLength;
|
||||||
|
public String maxAiOpponents;
|
||||||
|
public boolean saveGameActivated;
|
||||||
|
public boolean authenticationActivated;
|
||||||
|
public String googleAccount;
|
||||||
|
public String mailgunApiKey;
|
||||||
|
public String mailgunDomain;
|
||||||
|
public String mailSmtpHost;
|
||||||
|
public String mailSmtpPort;
|
||||||
|
public String mailUser;
|
||||||
|
public String mailPassword;
|
||||||
|
public String mailFromAddress;
|
||||||
|
public List<Plugin> playerTypes = Collections.emptyList();
|
||||||
|
public List<GamePlugin> gameTypes = Collections.emptyList();
|
||||||
|
public List<GamePlugin> tournamentTypes = Collections.emptyList();
|
||||||
|
public List<Plugin> draftCubes = Collections.emptyList();
|
||||||
|
public List<Plugin> deckTypes = Collections.emptyList();
|
||||||
|
|
||||||
|
private ConfigBuilder() {
|
||||||
|
super(ConfigBuilder::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Config makeValue() {
|
||||||
|
final Config result = new Config();
|
||||||
|
result.setServer(makeServer());
|
||||||
|
result.setPlayerTypes(makePlayerTypes());
|
||||||
|
result.setGameTypes(makeGameTypes());
|
||||||
|
result.setTournamentTypes(makeTournamentTypes());
|
||||||
|
result.setDraftCubes(makeDraftCubes());
|
||||||
|
result.setDeckTypes(makeDeckTypes());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Server makeServer() {
|
||||||
|
final Server server = new Server();
|
||||||
|
server.setServerAddress(serverAddress);
|
||||||
|
server.setServerName(serverName);
|
||||||
|
server.setPort(BigInteger.valueOf(port));
|
||||||
|
server.setSecondaryBindPort(bi(secondaryBindPort));
|
||||||
|
server.setLeasePeriod(bi(leasePeriod));
|
||||||
|
server.setSocketWriteTimeout(bi(socketWriteTimeout));
|
||||||
|
server.setMaxPoolSize(bi(maxPoolSize));
|
||||||
|
server.setNumAcceptThreads(bi(numAcceptThreads));
|
||||||
|
server.setBacklogSize(bi(backlogSize));
|
||||||
|
server.setMaxGameThreads(bi(maxGameThreads));
|
||||||
|
server.setMaxSecondsIdle(bi(maxSecondsIdle));
|
||||||
|
server.setMinUserNameLength(bi(minUsernameLength));
|
||||||
|
server.setMaxUserNameLength(bi(maxUsernameLength));
|
||||||
|
server.setInvalidUserNamePattern(invalidUsernamePattern);
|
||||||
|
server.setMinPasswordLength(bi(minPasswordLength));
|
||||||
|
server.setMaxPasswordLength(bi(maxPasswordLength));
|
||||||
|
server.setMaxAiOpponents(maxAiOpponents);
|
||||||
|
server.setSaveGameActivated(saveGameActivated);
|
||||||
|
server.setAuthenticationActivated(authenticationActivated);
|
||||||
|
server.setGoogleAccount(googleAccount);
|
||||||
|
server.setMailgunApiKey(mailgunApiKey);
|
||||||
|
server.setMailgunDomain(mailgunDomain);
|
||||||
|
server.setMailSmtpHost(mailSmtpHost);
|
||||||
|
server.setMailSmtpPort(mailSmtpPort);
|
||||||
|
server.setMailUser(mailUser);
|
||||||
|
server.setMailPassword(mailPassword);
|
||||||
|
server.setMailFromAddress(mailFromAddress);
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlayerTypes makePlayerTypes() {
|
||||||
|
final PlayerTypes playerTypes = new PlayerTypes();
|
||||||
|
this.playerTypes.forEach(p -> playerTypes.getPlayerType().add(p));
|
||||||
|
return playerTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameTypes makeGameTypes() {
|
||||||
|
final GameTypes gameTypes = new GameTypes();
|
||||||
|
this.gameTypes.forEach(g -> gameTypes.getGameType().add(g));
|
||||||
|
return gameTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TournamentTypes makeTournamentTypes() {
|
||||||
|
final TournamentTypes tournamentTypes = new TournamentTypes();
|
||||||
|
this.tournamentTypes.forEach(t -> tournamentTypes.getTournamentType().add(t));
|
||||||
|
return tournamentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DraftCubes makeDraftCubes() {
|
||||||
|
final DraftCubes draftCubes = new DraftCubes();
|
||||||
|
this.draftCubes.forEach(d -> draftCubes.getDraftCube().add(d));
|
||||||
|
return draftCubes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeckTypes makeDeckTypes() {
|
||||||
|
final DeckTypes deckTypes = new DeckTypes();
|
||||||
|
this.deckTypes.forEach(d -> deckTypes.getDeckType().add(d));
|
||||||
|
return deckTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigInteger bi(int value) {
|
||||||
|
return BigInteger.valueOf(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigBuilder baseConfigBuilder() {
|
||||||
|
return new ConfigBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String expectedString = RandomStringUtils.randomAlphanumeric(15);
|
||||||
|
private final int expectedPositiveInt = RandomUtils.nextInt(0, Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
|
||||||
|
@TestFactory
|
||||||
|
@DisplayName("should return from server")
|
||||||
|
Stream<DynamicTest> assignmentFromServer() {
|
||||||
|
return Stream.of(
|
||||||
|
testString("server address", c -> c.serverAddress = expectedString, ConfigWrapper::getServerAddress),
|
||||||
|
testString("server name", c -> c.serverName = expectedString, ConfigWrapper::getServerName),
|
||||||
|
testInt("port", c -> c.port = expectedPositiveInt, ConfigWrapper::getPort),
|
||||||
|
testInt("secondary bind port", c -> c.secondaryBindPort = expectedPositiveInt, ConfigWrapper::getSecondaryBindPort),
|
||||||
|
testInt("lease period", c -> c.leasePeriod = expectedPositiveInt, ConfigWrapper::getLeasePeriod),
|
||||||
|
testInt("socket write timeout", c -> c.socketWriteTimeout = expectedPositiveInt, ConfigWrapper::getSocketWriteTimeout),
|
||||||
|
testInt("max pool size", c -> c.maxPoolSize = expectedPositiveInt, ConfigWrapper::getMaxPoolSize),
|
||||||
|
testInt("number of accept threads", c -> c.numAcceptThreads = expectedPositiveInt, ConfigWrapper::getNumAcceptThreads),
|
||||||
|
testInt("backlog size", c -> c.backlogSize = expectedPositiveInt, ConfigWrapper::getBacklogSize),
|
||||||
|
testInt("max game threads", c -> c.maxGameThreads = expectedPositiveInt, ConfigWrapper::getMaxGameThreads),
|
||||||
|
testInt("max seconds idle", c -> c.maxSecondsIdle = expectedPositiveInt, ConfigWrapper::getMaxSecondsIdle),
|
||||||
|
testInt("min username length", c -> c.minUsernameLength = expectedPositiveInt, ConfigWrapper::getMinUserNameLength),
|
||||||
|
testInt("max username length", c -> c.maxUsernameLength = expectedPositiveInt, ConfigWrapper::getMaxUserNameLength),
|
||||||
|
testString("invalid username pattern", c -> c.invalidUsernamePattern = expectedString, ConfigWrapper::getInvalidUserNamePattern),
|
||||||
|
testInt("min password length", c -> c.minPasswordLength = expectedPositiveInt, ConfigWrapper::getMinPasswordLength),
|
||||||
|
testInt("max password length", c -> c.maxPasswordLength = expectedPositiveInt, ConfigWrapper::getMaxPasswordLength),
|
||||||
|
testString("max AI opponents", c -> c.maxAiOpponents = expectedString, ConfigWrapper::getMaxAiOpponents),
|
||||||
|
testTrue("save game activated", c -> c.saveGameActivated = true, ConfigWrapper::isSaveGameActivated),
|
||||||
|
testTrue("authentication activated", c -> c.authenticationActivated = true, ConfigWrapper::isAuthenticationActivated),
|
||||||
|
testString("google account", c -> c.googleAccount = expectedString, ConfigWrapper::getGoogleAccount),
|
||||||
|
testString("mailgun api key", c -> c.mailgunApiKey = expectedString, ConfigWrapper::getMailgunApiKey),
|
||||||
|
testString("mailgun domain", c -> c.mailgunDomain = expectedString, ConfigWrapper::getMailgunDomain),
|
||||||
|
testString("mail smtp host", c -> c.mailSmtpHost = expectedString, ConfigWrapper::getMailSmtpHost),
|
||||||
|
testString("mail smtp port", c -> c.mailSmtpPort = expectedString, ConfigWrapper::getMailSmtpPort),
|
||||||
|
testString("mail from address", c -> c.mailFromAddress = expectedString, ConfigWrapper::getMailFromAddress),
|
||||||
|
testString("mail user", c -> c.mailUser = expectedString, ConfigWrapper::getMailUser),
|
||||||
|
testString("mail password", c -> c.mailPassword = expectedString, ConfigWrapper::getMailPassword)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DynamicTest testString(String description, Consumer<ConfigBuilder> builderSetter, Function<ConfigWrapper, Object> valueExtractor) {
|
||||||
|
return testTemplate(description, builderSetter, valueExtractor, expectedString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DynamicTest testTemplate(String description, Consumer<ConfigBuilder> builderSetter, Function<ConfigWrapper, Object> valueExtractor, Object expectedValue) {
|
||||||
|
return DynamicTest.dynamicTest(description, () -> assertThat(valueExtractor.apply(makeTestee(baseConfigBuilder().with(builderSetter)))).isEqualTo(expectedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigWrapper makeTestee(ConfigBuilder builder) {
|
||||||
|
return new ConfigWrapper(builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private DynamicTest testInt(String description, Consumer<ConfigBuilder> builderSetter, Function<ConfigWrapper, Object> valueExtractor) {
|
||||||
|
return testTemplate(description, builderSetter, valueExtractor, expectedPositiveInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DynamicTest testTrue(String description, Consumer<ConfigBuilder> builderSetter, Function<ConfigWrapper, Object> valueExtractor) {
|
||||||
|
return testTemplate(description, builderSetter, valueExtractor, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final Comparator<Plugin> pluginComparator = (p1, p2) -> {
|
||||||
|
if (Objects.equals(p1.getName(), p2.getName()) &&
|
||||||
|
Objects.equals(p1.getJar(), p2.getJar()) &&
|
||||||
|
Objects.equals(p1.getClassName(), p2.getClassName())) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Comparator<GamePlugin> gamePluginComparator = (p1, p2) -> {
|
||||||
|
if (Objects.equals(p1.getName(), p2.getName()) &&
|
||||||
|
Objects.equals(p1.getJar(), p2.getJar()) &&
|
||||||
|
Objects.equals(p1.getClassName(), p2.getClassName()) &&
|
||||||
|
Objects.equals(p1.getTypeName(), p2.getTypeName())) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final List<Plugin> randomPlugins = IntStream.range(0, RandomUtils.nextInt(1, 10))
|
||||||
|
.mapToObj(i -> makePlugin(
|
||||||
|
RandomStringUtils.randomAlphanumeric(15),
|
||||||
|
RandomStringUtils.randomAlphanumeric(16),
|
||||||
|
RandomStringUtils.randomAlphanumeric(17))
|
||||||
|
).collect(Collectors.toList());
|
||||||
|
private final List<GamePlugin> randomGamePlugins = IntStream.range(0, RandomUtils.nextInt(1, 10))
|
||||||
|
.mapToObj(i -> makeGamePlugin(
|
||||||
|
RandomStringUtils.randomAlphanumeric(15),
|
||||||
|
RandomStringUtils.randomAlphanumeric(16),
|
||||||
|
RandomStringUtils.randomAlphanumeric(17),
|
||||||
|
RandomStringUtils.randomAlphanumeric(18))
|
||||||
|
).collect(Collectors.toList());
|
||||||
|
|
||||||
|
private Plugin makePlugin(String name, String jar, String className) {
|
||||||
|
final Plugin plugin = new Plugin();
|
||||||
|
plugin.setName(name);
|
||||||
|
plugin.setJar(jar);
|
||||||
|
plugin.setClassName(className);
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GamePlugin makeGamePlugin(String name, String jar, String className, String typeName) {
|
||||||
|
final GamePlugin plugin = new GamePlugin();
|
||||||
|
plugin.setName(name);
|
||||||
|
plugin.setJar(jar);
|
||||||
|
plugin.setClassName(className);
|
||||||
|
plugin.setTypeName(typeName);
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestFactory
|
||||||
|
@DisplayName("should extract")
|
||||||
|
Stream<DynamicTest> pluginsExtraction() {
|
||||||
|
return Stream.of(
|
||||||
|
pluginTest("playerTypes from playerTypes", c -> c.playerTypes = randomPlugins, ConfigWrapper::getPlayerTypes),
|
||||||
|
gamePluginTest("gameTypes from gameTypes", c -> c.gameTypes = randomGamePlugins, ConfigWrapper::getGameTypes),
|
||||||
|
gamePluginTest("tournamentTypes from tournamentTypes", c -> c.tournamentTypes = randomGamePlugins, ConfigWrapper::getTournamentTypes),
|
||||||
|
pluginTest("draftCubes from draftCubes", c -> c.draftCubes = randomPlugins, ConfigWrapper::getDraftCubes),
|
||||||
|
pluginTest("deckTypes from deckTypes", c -> c.deckTypes = randomPlugins, ConfigWrapper::getDeckTypes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DynamicTest pluginTest(String description,
|
||||||
|
Consumer<ConfigBuilder> builderSetter,
|
||||||
|
Function<ConfigWrapper, List<Plugin>> listExtractor) {
|
||||||
|
return testTemplateForLists(description, builderSetter, listExtractor, randomPlugins, pluginComparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DynamicTest gamePluginTest(String description,
|
||||||
|
Consumer<ConfigBuilder> builderSetter,
|
||||||
|
Function<ConfigWrapper, List<GamePlugin>> listExtractor) {
|
||||||
|
return testTemplateForLists(description, builderSetter, listExtractor, randomGamePlugins, gamePluginComparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> DynamicTest testTemplateForLists(String description,
|
||||||
|
Consumer<ConfigBuilder> builderSetter,
|
||||||
|
Function<ConfigWrapper, List<T>> listExtractor,
|
||||||
|
List<T> expectedValue,
|
||||||
|
Comparator<T> comparator) {
|
||||||
|
return DynamicTest.dynamicTest(description, () ->
|
||||||
|
assertThat(listExtractor.apply(makeTestee(baseConfigBuilder().with(builderSetter))))
|
||||||
|
.usingElementComparator(comparator)
|
||||||
|
.containsExactlyElementsOf(expectedValue)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
27
pom.xml
27
pom.xml
|
@ -52,6 +52,18 @@
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.2</version>
|
||||||
|
<configuration>
|
||||||
|
<argLine>-Dfile.encoding=UTF-8</argLine>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
</build>
|
</build>
|
||||||
<modules>
|
<modules>
|
||||||
<module>Mage</module>
|
<module>Mage</module>
|
||||||
|
@ -113,6 +125,21 @@
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>29.0-jre</version>
|
<version>29.0-jre</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>5.7.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>3.18.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.11</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
</project>
|
</project>
|
||||||
|
|
Loading…
Reference in a new issue