package pluginbase.testingbukkit;
import org.bukkit.*;
import org.bukkit.World.Environment;
import org.bukkit.entity.Player;
import org.bukkit.help.HelpMap;
import org.bukkit.plugin.ServicesManager;
import org.bukkit.plugin.SimpleServicesManager;
import org.bukkit.scheduler.BukkitScheduler;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import pluginbase.logging.Logging;
import pluginbase.testingbukkit.answers.NoArgVoidAnswer;
import pluginbase.testingbukkit.answers.SetterAnswer;
import pluginbase.testingbukkit.plugin.TestingPluginManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import static org.mockito.Matchers.*;
import static org.powermock.api.mockito.PowerMockito.*;
public final class ServerFactory {
private static class ServerData {
private List<World> worlds = new ArrayList<World>();
private List<Player> onlinePlayers = new ArrayList<Player>();
private boolean allowEnd = true;
private boolean allowNether = true;
private GameMode defaultGameMode = GameMode.SURVIVAL;
private int monsterSpawn = 70;
private int animalSpawn = 15;
private int waterAnimalSpawn = 5;
private int ambientSpawn = 15;
private int ticksPerMonsterSpawn = 1;
private int ticksPerAnimalSpawn = 400;
private TestingPluginManager pluginManager;
private BukkitScheduler bukkitScheduler = PowerMockito.mock(BukkitScheduler.class);
private ServicesManager servicesManager = new SimpleServicesManager();
private HelpMap helpMap = mock(HelpMap.class);
ServerData(Server server) {
pluginManager = new TestingPluginManager(server);
}
}
public static TestingServer createTestingServer() {
final TestingServer server = mock(TestingServer.class);
final ServerData data = new ServerData(server);
when(server.getName()).thenReturn("MockBukkit");
when(server.getVersion()).thenReturn("0.0.1");
when(server.getBukkitVersion()).thenReturn("1.8.7-R0.1-SNAPSHOT");
when(server.getOnlinePlayers()).thenAnswer(new Answer<Collection<Player>>() {
@Override
public Collection<Player> answer(InvocationOnMock invocationOnMock) throws Throwable {
return data.onlinePlayers;
}
});
when(server.getMaxPlayers()).thenReturn(Integer.MAX_VALUE);
when(server.getPort()).thenReturn(25565);
when(server.getViewDistance()).thenReturn(15);
when(server.getIp()).thenReturn("127.0.0.1");
when(server.getServerName()).thenReturn("MockBukkit");
when(server.getServerId()).thenReturn("1");
when(server.getWorldType()).thenReturn("DEFAULT");
when(server.getGenerateStructures()).thenReturn(true);
doAnswer(new SetterAnswer<Boolean>() {
@Override
public void set(Boolean value) {
data.allowEnd = value;
}
}).when(server).setAllowEnd(anyBoolean());
when(server.getAllowEnd()).thenAnswer(new Answer<Boolean>() {
@Override
public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable {
return data.allowEnd;
}
});
doAnswer(new SetterAnswer<Boolean>() {
@Override
protected void set(Boolean value) {
data.allowNether = value;
}
}).when(server).setAllowNether(anyBoolean());
when(server.getAllowNether()).thenAnswer(new Answer<Boolean>() {
@Override
public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable {
return data.allowNether;
}
});
when(server.broadcastMessage(anyString())).thenAnswer(new Answer<Integer>() {
@Override
public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
String message = (String) invocationOnMock.getArguments()[0];
for (Player player : data.onlinePlayers) {
player.sendMessage(message);
}
return data.onlinePlayers.size();
}
});
when(server.getUpdateFolder()).thenReturn(FileLocations.UPDATES_DIRECTORY.toString());
when(server.getUpdateFolderFile()).thenReturn(FileLocations.UPDATES_DIRECTORY);
doAnswer(new SetterAnswer<Integer>() {
@Override
protected void set(Integer value) {
data.ticksPerAnimalSpawn = value;
}
}).when(server).setTicksPerAnimalSpawn(anyInt());
doAnswer(new SetterAnswer<Integer>() {
@Override
protected void set(Integer value) {
data.ticksPerMonsterSpawn = value;
}
}).when(server).setTicksPerMonsterSpawn(anyInt());
when(server.getTicksPerAnimalSpawns()).thenAnswer(new Answer<Integer>() {
@Override
public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
return data.ticksPerAnimalSpawn;
}
});
when(server.getTicksPerMonsterSpawns()).thenAnswer(new Answer<Integer>() {
@Override
public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
return data.ticksPerMonsterSpawn;
}
});
when(server.getPlayer(anyString())).thenAnswer(new Answer<Player>() {
@Override
public Player answer(InvocationOnMock invocationOnMock) throws Throwable {
String s = (String) invocationOnMock.getArguments()[0];
s = s.toLowerCase();
for (Player player : data.onlinePlayers) {
if (player.getName().toLowerCase().startsWith(s)) {
return player;
}
}
return null;
}
});
when(server.getPlayerExact(anyString())).thenAnswer(new Answer<Player>() {
@Override
public Player answer(InvocationOnMock invocationOnMock) throws Throwable {
String s = (String) invocationOnMock.getArguments()[0];
for (Player player : data.onlinePlayers) {
if (player.getName().equals(s)) {
return player;
}
}
return null;
}
});
when(server.getPlayer(any(UUID.class))).thenAnswer(new Answer<Player>() {
@Override
public Player answer(InvocationOnMock invocationOnMock) throws Throwable {
UUID uuid = (UUID) invocationOnMock.getArguments()[0];
for (Player player : data.onlinePlayers) {
if (player.getUniqueId().equals(uuid)) {
return player;
}
}
return null;
}
});
when(server.getPluginManager()).thenReturn(data.pluginManager);
when(server.getScheduler()).thenReturn(data.bukkitScheduler);
when(server.getServicesManager()).thenReturn(data.servicesManager);
when(server.getWorlds()).thenReturn(data.worlds);
when(server.createWorld(any(WorldCreator.class))).thenAnswer(new Answer<World>() {
@Override
public World answer(InvocationOnMock invocationOnMock) throws Throwable {
World world = WorldFactory.createWorld((WorldCreator) invocationOnMock.getArguments()[0]);
data.worlds.add(world);
return world;
}
});
when(server.unloadWorld(anyString(), anyBoolean())).thenAnswer(new Answer<Boolean>() {
@Override
public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable {
World world = server.getWorld((String) invocationOnMock.getArguments()[0]);
return server.unloadWorld(world, (Boolean) invocationOnMock.getArguments()[1]);
}
});
when(server.unloadWorld(any(World.class), anyBoolean())).thenAnswer(new Answer<Boolean>() {
@Override
public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable {
World world = (World) invocationOnMock.getArguments()[0];
if (world != null) {
return data.worlds.remove(world);
}
return false;
}
});
when(server.getWorld(anyString())).thenAnswer(new Answer<World>() {
@Override
public World answer(InvocationOnMock invocationOnMock) throws Throwable {
String s = (String) invocationOnMock.getArguments()[0];
for (World w : data.worlds) {
if (w.getName().equals(s)) {
return w;
}
}
return null;
}
});
when(server.getWorld(any(UUID.class))).thenAnswer(new Answer<World>() {
@Override
public World answer(InvocationOnMock invocationOnMock) throws Throwable {
UUID uuid = (UUID) invocationOnMock.getArguments()[0];
for (World w : data.worlds) {
if (w.getUID().equals(uuid)) {
return w;
}
}
return null;
}
});
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
server.createWorld(new WorldCreator("world").environment(Environment.NORMAL));
server.createWorld(new WorldCreator("world_nether").environment(Environment.NETHER));
server.createWorld(new WorldCreator("world_the_end").environment(Environment.THE_END));
return null;
}
}).when(server).loadDefaultWorlds();
doAnswer(new NoArgVoidAnswer() {
@Override
protected void call() {
// gonna need this apparently...
}
}).when(server).reload();
when(server.getLogger()).thenReturn(Logging.getLogger());
when(server.getOnlineMode()).thenReturn(true);
when(server.getAllowFlight()).thenReturn(true);
when(server.isHardcore()).thenReturn(false);
when(server.useExactLoginLocation()).thenReturn(true);
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
System.out.println("Saving worlds...");
for (World world : data.worlds) {
world.save();
}
return null;
}
}).when(server).shutdown();
when(server.getDefaultGameMode()).thenAnswer(new Answer<GameMode>() {
@Override
public GameMode answer(InvocationOnMock invocationOnMock) throws Throwable {
return data.defaultGameMode;
}
});
doAnswer(new SetterAnswer<GameMode>() {
@Override
protected void set(GameMode value) {
data.defaultGameMode = value;
}
}).when(server).setDefaultGameMode(any(GameMode.class));
when(server.getWorldContainer()).thenReturn(FileLocations.WORLDS_DIRECTORY);
when(server.getOfflinePlayers()).thenReturn(new OfflinePlayer[0]);
when(server.getHelpMap()).thenReturn(data.helpMap);
when(server.getMonsterSpawnLimit()).thenReturn(data.monsterSpawn);
when(server.getAnimalSpawnLimit()).thenReturn(data.animalSpawn);
when(server.getWaterAnimalSpawnLimit()).thenReturn(data.waterAnimalSpawn);
when(server.getAmbientSpawnLimit()).thenReturn(data.ambientSpawn);
when(server.isPrimaryThread()).thenReturn(true);
when(server.getMotd()).thenReturn("Hello, world");
when(server.getShutdownMessage()).thenReturn("Server shutting down...");
when(server._INVALID_getOnlinePlayers()).thenReturn(data.onlinePlayers.toArray(new Player[data.onlinePlayers.size()]));
return server;
}
private ServerFactory() { }
}