Moved TestWorldDiskIO to a subpackage and introduced some abstractions
This commit is contained in:
parent
41a2909f7c
commit
cd16334db8
@ -46,6 +46,7 @@ import ru.windcorp.progressia.server.world.context.impl.DefaultServerContext;
|
||||
import ru.windcorp.progressia.server.world.context.impl.ReportingServerContext;
|
||||
import ru.windcorp.progressia.server.world.context.impl.RotatingServerContext;
|
||||
import ru.windcorp.progressia.server.world.generation.WorldGenerator;
|
||||
import ru.windcorp.progressia.server.world.io.WorldContainer;
|
||||
import ru.windcorp.progressia.server.world.tasks.WorldAccessor;
|
||||
import ru.windcorp.progressia.server.world.ticking.Change;
|
||||
import ru.windcorp.progressia.server.world.ticking.Evaluation;
|
||||
@ -78,11 +79,16 @@ public class Server {
|
||||
|
||||
private final TickingSettings tickingSettings = new TickingSettings();
|
||||
|
||||
public Server(DefaultWorldData world, Function<Server, WorldGenerator> generatorCreator) {
|
||||
public Server(
|
||||
DefaultWorldData world,
|
||||
Function<Server, WorldGenerator> generatorCreator,
|
||||
WorldContainer worldContainer
|
||||
) {
|
||||
this.world = new DefaultWorldLogic(
|
||||
world,
|
||||
this,
|
||||
generatorCreator.apply(this),
|
||||
worldContainer,
|
||||
worldAccessor
|
||||
);
|
||||
this.serverThread = new ServerThread(this);
|
||||
@ -349,6 +355,7 @@ public class Server {
|
||||
public void shutdown(String message) {
|
||||
LogManager.getLogger().warn("Server.shutdown() is not yet implemented");
|
||||
serverThread.stop();
|
||||
getWorld().getContainer().close();
|
||||
}
|
||||
|
||||
private void scheduleWorldTicks(Server server) {
|
||||
|
@ -18,8 +18,14 @@
|
||||
|
||||
package ru.windcorp.progressia.server;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.Function;
|
||||
|
||||
import ru.windcorp.progressia.common.world.DefaultWorldData;
|
||||
import ru.windcorp.progressia.server.world.generation.WorldGenerator;
|
||||
import ru.windcorp.progressia.server.world.io.WorldContainer;
|
||||
import ru.windcorp.progressia.test.gen.TestGenerationConfig;
|
||||
import ru.windcorp.progressia.test.region.RegionFormat;
|
||||
|
||||
public class ServerState {
|
||||
|
||||
@ -34,9 +40,14 @@ public class ServerState {
|
||||
}
|
||||
|
||||
public static void startServer() {
|
||||
Server server = new Server(new DefaultWorldData(), TestGenerationConfig.createGenerator());
|
||||
|
||||
Function<Server, WorldGenerator> generator = new TestGenerationConfig().getGenerator();
|
||||
WorldContainer container = new RegionFormat("Test:Region").create(Paths.get("tmp_world"));
|
||||
|
||||
Server server = new Server(new DefaultWorldData(), generator, container);
|
||||
setInstance(server);
|
||||
server.start();
|
||||
|
||||
}
|
||||
|
||||
private ServerState() {
|
||||
|
@ -24,7 +24,7 @@ import ru.windcorp.progressia.common.world.PacketSendChunk;
|
||||
import ru.windcorp.progressia.common.world.DefaultWorldData;
|
||||
import ru.windcorp.progressia.server.Player;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.test.TestWorldDiskIO;
|
||||
import ru.windcorp.progressia.server.world.io.WorldContainer;
|
||||
|
||||
/**
|
||||
* Chunk manager provides facilities to load, unload and generate chunks for a
|
||||
@ -52,6 +52,10 @@ public class ChunkManager {
|
||||
return getLoadManager().getServer();
|
||||
}
|
||||
|
||||
public WorldContainer getContainer() {
|
||||
return getServer().getWorld().getContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the result of an attempt to load a chunk.
|
||||
*/
|
||||
@ -115,7 +119,7 @@ public class ChunkManager {
|
||||
|
||||
DefaultWorldData world = getServer().getWorld().getData();
|
||||
|
||||
DefaultChunkData chunk = TestWorldDiskIO.tryToLoad(chunkPos, world, getServer());
|
||||
DefaultChunkData chunk = getServer().getWorld().getContainer().load(chunkPos, world, getServer());
|
||||
if (chunk != null) {
|
||||
world.addChunk(chunk);
|
||||
return LoadResult.LOADED_FROM_DISK;
|
||||
@ -141,7 +145,7 @@ public class ChunkManager {
|
||||
}
|
||||
|
||||
world.removeChunk(chunk);
|
||||
TestWorldDiskIO.saveChunk(chunk, getServer());
|
||||
getContainer().save(chunk, getServer().getWorld().getData(), getServer());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import ru.windcorp.progressia.common.world.WorldDataListener;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.server.world.generation.WorldGenerator;
|
||||
import ru.windcorp.progressia.server.world.io.WorldContainer;
|
||||
import ru.windcorp.progressia.server.world.tasks.TickEntitiesTask;
|
||||
import ru.windcorp.progressia.server.world.tasks.WorldAccessor;
|
||||
import ru.windcorp.progressia.server.world.ticking.Evaluation;
|
||||
@ -42,18 +43,21 @@ public class DefaultWorldLogic implements WorldLogic {
|
||||
private final Server server;
|
||||
|
||||
private final WorldGenerator generator;
|
||||
private final WorldContainer container;
|
||||
|
||||
private final Map<DefaultChunkData, DefaultChunkLogic> chunks = new HashMap<>();
|
||||
|
||||
private final Evaluation tickEntitiesTask = new TickEntitiesTask();
|
||||
|
||||
public DefaultWorldLogic(DefaultWorldData data, Server server, WorldGenerator generator, WorldAccessor accessor) {
|
||||
public DefaultWorldLogic(DefaultWorldData data, Server server, WorldGenerator generator, WorldContainer container, WorldAccessor accessor) {
|
||||
this.data = data;
|
||||
this.server = server;
|
||||
|
||||
this.generator = generator;
|
||||
data.setGravityModel(getGenerator().getGravityModel());
|
||||
|
||||
this.container = container;
|
||||
|
||||
data.addListener(new WorldDataListener() {
|
||||
@Override
|
||||
public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) {
|
||||
@ -106,6 +110,10 @@ public class DefaultWorldLogic implements WorldLogic {
|
||||
return generator;
|
||||
}
|
||||
|
||||
public WorldContainer getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
public DefaultChunkData generate(Vec3i chunkPos) {
|
||||
DefaultChunkData chunk = getGenerator().generate(chunkPos);
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Progressia
|
||||
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ru.windcorp.progressia.server.world.io;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.DefaultChunkData;
|
||||
import ru.windcorp.progressia.common.world.DefaultWorldData;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
|
||||
public interface WorldContainer {
|
||||
|
||||
Path getPath();
|
||||
|
||||
DefaultChunkData load(Vec3i position, DefaultWorldData world, Server server);
|
||||
|
||||
void save(DefaultChunkData chunk, DefaultWorldData world, Server server);
|
||||
|
||||
void close();
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Progressia
|
||||
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ru.windcorp.progressia.server.world.io;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
|
||||
public abstract class WorldContainerFormat extends Namespaced {
|
||||
|
||||
public WorldContainerFormat(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public abstract WorldContainer create(Path directory);
|
||||
|
||||
}
|
@ -49,9 +49,18 @@ public class TestGenerationConfig {
|
||||
private static final float CURVATURE = Units.get("100 m");
|
||||
private static final float INNER_RADIUS = Units.get("200 m");
|
||||
|
||||
private static final Fields FIELDS = new Fields(SEED);
|
||||
private final Fields fields = new Fields(SEED);
|
||||
private final Function<Server, WorldGenerator> generator;
|
||||
|
||||
public static Function<Server, WorldGenerator> createGenerator() {
|
||||
public TestGenerationConfig() {
|
||||
this.generator = createGenerator();
|
||||
}
|
||||
|
||||
public Function<Server, WorldGenerator> getGenerator() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
private Function<Server, WorldGenerator> createGenerator() {
|
||||
|
||||
Planet planet = new Planet(
|
||||
((int) PLANET_RADIUS) / Coordinates.CHUNK_SIZE,
|
||||
@ -60,7 +69,7 @@ public class TestGenerationConfig {
|
||||
INNER_RADIUS
|
||||
);
|
||||
|
||||
TestHeightMap heightMap = new TestHeightMap(planet, planet.getRadius() / 4, FIELDS);
|
||||
TestHeightMap heightMap = new TestHeightMap(planet, planet.getRadius() / 4, fields);
|
||||
|
||||
FloatRangeMap<TerrainLayer> layers = new ArrayFloatRangeMap<>();
|
||||
registerTerrainLayers(layers);
|
||||
@ -72,11 +81,11 @@ public class TestGenerationConfig {
|
||||
|
||||
}
|
||||
|
||||
private static void registerTerrainLayers(FloatRangeMap<TerrainLayer> layers) {
|
||||
private void registerTerrainLayers(FloatRangeMap<TerrainLayer> layers) {
|
||||
BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt");
|
||||
BlockData air = BlockDataRegistry.getInstance().get("Test:Air");
|
||||
|
||||
SurfaceFloatField cliffs = FIELDS.get("Test:Cliff");
|
||||
SurfaceFloatField cliffs = fields.get("Test:Cliff");
|
||||
|
||||
WorleyProceduralNoise.Builder<TerrainLayer> builder = WorleyProceduralNoise.builder();
|
||||
TestContent.ROCKS.getRocks().forEach(rock -> {
|
||||
@ -88,9 +97,9 @@ public class TestGenerationConfig {
|
||||
}
|
||||
}, 1);
|
||||
});
|
||||
SurfaceFloatField rockDepthOffsets = FIELDS.register(
|
||||
SurfaceFloatField rockDepthOffsets = fields.register(
|
||||
"Test:RockDepthOffsets",
|
||||
() -> tweak(FIELDS.primitive(), 40, 5)
|
||||
() -> tweak(fields.primitive(), 40, 5)
|
||||
);
|
||||
RockLayer rockLayer = new RockLayer(builder.build(SEED), rockDepthOffsets);
|
||||
|
||||
@ -105,28 +114,28 @@ public class TestGenerationConfig {
|
||||
layers.put(4, Float.POSITIVE_INFINITY, rockLayer);
|
||||
}
|
||||
|
||||
private static void registerFeatures(List<SurfaceFeature> features) {
|
||||
private void registerFeatures(List<SurfaceFeature> features) {
|
||||
|
||||
SurfaceFloatField forestiness = FIELDS.register(
|
||||
SurfaceFloatField forestiness = fields.register(
|
||||
"Test:Forest",
|
||||
() -> squash(scale(FIELDS.primitive(), 200), 5)
|
||||
() -> squash(scale(fields.primitive(), 200), 5)
|
||||
);
|
||||
|
||||
SurfaceFloatField grassiness = FIELDS.register(
|
||||
SurfaceFloatField grassiness = fields.register(
|
||||
"Test:Grass",
|
||||
f -> multiply(
|
||||
tweak(octaves(FIELDS.primitive(), 2, 2), 40, 0.5, 1.2),
|
||||
squash(tweak(FIELDS.get("Test:Forest", f), 1, -1, 1), 10),
|
||||
anti(squash(FIELDS.get("Test:Cliff", f), 10))
|
||||
tweak(octaves(fields.primitive(), 2, 2), 40, 0.5, 1.2),
|
||||
squash(tweak(fields.get("Test:Forest", f), 1, -1, 1), 10),
|
||||
anti(squash(fields.get("Test:Cliff", f), 10))
|
||||
)
|
||||
);
|
||||
|
||||
Function<String, SurfaceFloatField> floweriness = flowerName -> FIELDS.register(
|
||||
Function<String, SurfaceFloatField> floweriness = flowerName -> fields.register(
|
||||
"Test:Flower" + flowerName,
|
||||
f -> multiply(
|
||||
selectPositive(squash(scale(octaves(FIELDS.primitive(), 2, 3), 100), 2), 1, 0.5),
|
||||
tweak(FIELDS.get("Test:Forest", f), 1, -1, 1.1),
|
||||
anti(squash(FIELDS.get("Test:Cliff", f), 10))
|
||||
selectPositive(squash(scale(octaves(fields.primitive(), 2, 3), 100), 2), 1, 0.5),
|
||||
tweak(fields.get("Test:Forest", f), 1, -1, 1.1),
|
||||
anti(squash(fields.get("Test:Cliff", f), 10))
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Progressia
|
||||
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ru.windcorp.progressia.test.region;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import ru.windcorp.progressia.server.world.io.WorldContainer;
|
||||
import ru.windcorp.progressia.server.world.io.WorldContainerFormat;
|
||||
|
||||
public class RegionFormat extends WorldContainerFormat {
|
||||
|
||||
public RegionFormat(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldContainer create(Path directory) {
|
||||
return new TestWorldDiskIO(directory);
|
||||
}
|
||||
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ru.windcorp.progressia.test;
|
||||
package ru.windcorp.progressia.test.region;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
@ -52,12 +52,13 @@ import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.DefaultWorldData;
|
||||
import ru.windcorp.progressia.common.world.io.ChunkIO;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.server.world.io.WorldContainer;
|
||||
|
||||
public class TestWorldDiskIO {
|
||||
public class TestWorldDiskIO implements WorldContainer {
|
||||
|
||||
private static final boolean resetCorrupted = true;
|
||||
|
||||
public static class RandomFileMapped {
|
||||
public class RandomFileMapped {
|
||||
public RandomAccessFile file;
|
||||
public HashMap<HashableVec3i, Integer> offsets;
|
||||
public HashMap<HashableVec3i, Integer> lengths;
|
||||
@ -121,11 +122,11 @@ public class TestWorldDiskIO {
|
||||
}
|
||||
}
|
||||
|
||||
private static Path SAVE_DIR = Paths.get("tmp_world");
|
||||
private Path SAVE_DIR = Paths.get("tmp_world");
|
||||
private static final String formatFile = "world.format";
|
||||
private static final Logger LOG = LogManager.getLogger("TestWorldDiskIO");
|
||||
|
||||
private static HashMap<HashableVec3i, RandomFileMapped> inOutMap;
|
||||
private HashMap<HashableVec3i, RandomFileMapped> inOutMap;
|
||||
private static final boolean ENABLE = false;
|
||||
|
||||
private static int maxSize = 1048576;
|
||||
@ -134,11 +135,11 @@ public class TestWorldDiskIO {
|
||||
private static final int bestFormat = 65536;
|
||||
|
||||
// private Map<Vec3i,Vec3i> regions = new HashMap<Vec3i,Vec3i>();
|
||||
private static Vec3i regionSize;
|
||||
private static int chunksPerRegion;
|
||||
private Vec3i regionSize;
|
||||
private int chunksPerRegion;
|
||||
|
||||
private static int currentFormat = -1;
|
||||
private static String extension = ".null";
|
||||
private int currentFormat = -1;
|
||||
private String extension = ".null";
|
||||
|
||||
private static int natFromInt(int loc) {
|
||||
if (loc < 0)
|
||||
@ -155,7 +156,7 @@ public class TestWorldDiskIO {
|
||||
* }
|
||||
*/
|
||||
|
||||
private static Vec3i getRegion(Vec3i chunkLoc) {
|
||||
private Vec3i getRegion(Vec3i chunkLoc) {
|
||||
int x = chunkLoc.x;
|
||||
if (x<0)
|
||||
{
|
||||
@ -197,15 +198,11 @@ public class TestWorldDiskIO {
|
||||
return ((a % m) + m) % m;
|
||||
}
|
||||
|
||||
private static Vec3i getRegionLoc(Vec3i chunkLoc) {
|
||||
private Vec3i getRegionLoc(Vec3i chunkLoc) {
|
||||
return new Vec3i(mod(chunkLoc.x, regionSize.x), mod(chunkLoc.y, regionSize.y), mod(chunkLoc.z, regionSize.z));
|
||||
}
|
||||
|
||||
public static void initRegions() {
|
||||
initRegions(null);
|
||||
}
|
||||
|
||||
public static void initRegions(Path worldPath) {
|
||||
public TestWorldDiskIO(Path worldPath) {
|
||||
if (worldPath != null) {
|
||||
SAVE_DIR = worldPath;
|
||||
}
|
||||
@ -224,7 +221,7 @@ public class TestWorldDiskIO {
|
||||
return sectorsUsed;
|
||||
}*/
|
||||
|
||||
private static void setRegionSize(int format) {
|
||||
private void setRegionSize(int format) {
|
||||
inOutMap = new HashMap<HashableVec3i, RandomFileMapped>();
|
||||
switch (format) {
|
||||
case 65536:
|
||||
@ -243,7 +240,7 @@ public class TestWorldDiskIO {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean confirmHeaderHealth(RandomAccessFile input, HashMap<HashableVec3i, Integer> offsets, HashMap<HashableVec3i, Integer> length) throws IOException
|
||||
public boolean confirmHeaderHealth(RandomAccessFile input, HashMap<HashableVec3i, Integer> offsets, HashMap<HashableVec3i, Integer> length) throws IOException
|
||||
{
|
||||
Set<Integer> used = new HashSet<Integer>();
|
||||
input.seek(0);
|
||||
@ -282,7 +279,8 @@ public class TestWorldDiskIO {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void saveChunk(DefaultChunkData chunk, Server server) {
|
||||
@Override
|
||||
public void save(DefaultChunkData chunk, DefaultWorldData world, Server server) {
|
||||
if (!ENABLE)
|
||||
return;
|
||||
|
||||
@ -472,7 +470,7 @@ public class TestWorldDiskIO {
|
||||
}
|
||||
}
|
||||
|
||||
private static RandomFileMapped makeNew(Path path, Object hashObj) {
|
||||
private RandomFileMapped makeNew(Path path, Object hashObj) {
|
||||
try
|
||||
{
|
||||
RandomAccessFile raf = new RandomAccessFile(path.toFile(), "rw");
|
||||
@ -490,12 +488,13 @@ public class TestWorldDiskIO {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void writeGenerationHint(DefaultChunkData chunk, DataOutputStream output, Server server)
|
||||
private void writeGenerationHint(DefaultChunkData chunk, DataOutputStream output, Server server)
|
||||
throws IOException {
|
||||
server.getWorld().getGenerator().writeGenerationHint(output, chunk.getGenerationHint());
|
||||
}
|
||||
|
||||
public static DefaultChunkData tryToLoad(Vec3i chunkPos, DefaultWorldData world, Server server) {
|
||||
@Override
|
||||
public DefaultChunkData load(Vec3i chunkPos, DefaultWorldData world, Server server) {
|
||||
if (!ENABLE)
|
||||
return null;
|
||||
|
||||
@ -650,7 +649,7 @@ public class TestWorldDiskIO {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static DefaultChunkData loadRegion(Path path, Vec3i chunkPos, DefaultWorldData world, Server server)
|
||||
private DefaultChunkData loadRegion(Path path, Vec3i chunkPos, DefaultWorldData world, Server server)
|
||||
throws IOException,
|
||||
DecodingException {
|
||||
int offset = 0;
|
||||
@ -724,7 +723,7 @@ public class TestWorldDiskIO {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static DefaultChunkData loadRegionX(Path path, Vec3i chunkPos, DefaultWorldData world, Server server)
|
||||
private DefaultChunkData loadRegionX(Path path, Vec3i chunkPos, DefaultWorldData world, Server server)
|
||||
throws IOException,
|
||||
DecodingException {
|
||||
int offset = 0;
|
||||
@ -810,4 +809,15 @@ public class TestWorldDiskIO {
|
||||
chunk.setGenerationHint(server.getWorld().getGenerator().readGenerationHint(input));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPath() {
|
||||
return SAVE_DIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user