diff --git a/src/main/java/ru/windcorp/jputil/ArrayUtil.java b/src/main/java/ru/windcorp/jputil/ArrayUtil.java index 4c849b7..04de6c4 100644 --- a/src/main/java/ru/windcorp/jputil/ArrayUtil.java +++ b/src/main/java/ru/windcorp/jputil/ArrayUtil.java @@ -33,7 +33,7 @@ public class ArrayUtil { } return -1; } - + public static int lastIndexOf(byte[] array, byte element) { for (int i = array.length - 1; i >= 0; --i) { if (array[i] == element) { @@ -42,7 +42,7 @@ public class ArrayUtil { } return -1; } - + public static int occurences(byte[] array, byte element) { int result = 0; for (int i = 0; i < array.length; ++i) { @@ -52,7 +52,7 @@ public class ArrayUtil { } return result; } - + public static int hasDuplicates(byte[] array) { for (int i = 0; i < array.length; ++i) { byte a = array[i]; @@ -62,10 +62,10 @@ public class ArrayUtil { } } } - + return -1; } - + public static int firstIndexOf(short[] array, short element) { for (int i = 0; i < array.length; ++i) { if (array[i] == element) { @@ -74,7 +74,7 @@ public class ArrayUtil { } return -1; } - + public static int lastIndexOf(short[] array, short element) { for (int i = array.length - 1; i >= 0; --i) { if (array[i] == element) { @@ -83,7 +83,7 @@ public class ArrayUtil { } return -1; } - + public static int occurences(short[] array, short element) { int result = 0; for (int i = 0; i < array.length; ++i) { @@ -93,7 +93,7 @@ public class ArrayUtil { } return result; } - + public static int hasDuplicates(short[] array) { for (int i = 0; i < array.length; ++i) { short a = array[i]; @@ -103,10 +103,10 @@ public class ArrayUtil { } } } - + return -1; } - + public static int firstIndexOf(int[] array, int element) { for (int i = 0; i < array.length; ++i) { if (array[i] == element) { @@ -115,7 +115,7 @@ public class ArrayUtil { } return -1; } - + public static int lastIndexOf(int[] array, int element) { for (int i = array.length - 1; i >= 0; --i) { if (array[i] == element) { @@ -124,7 +124,7 @@ public class ArrayUtil { } return -1; } - + public static int occurences(int[] array, int element) { int result = 0; for (int i = 0; i < array.length; ++i) { @@ -134,7 +134,7 @@ public class ArrayUtil { } return result; } - + public static int hasDuplicates(int[] array) { for (int i = 0; i < array.length; ++i) { int a = array[i]; @@ -144,10 +144,10 @@ public class ArrayUtil { } } } - + return -1; } - + public static int firstIndexOf(long[] array, long element) { for (int i = 0; i < array.length; ++i) { if (array[i] == element) { @@ -156,7 +156,7 @@ public class ArrayUtil { } return -1; } - + public static int lastIndexOf(long[] array, long element) { for (int i = array.length - 1; i >= 0; --i) { if (array[i] == element) { @@ -165,7 +165,7 @@ public class ArrayUtil { } return -1; } - + public static int occurences(long[] array, long element) { int result = 0; for (int i = 0; i < array.length; ++i) { @@ -175,7 +175,7 @@ public class ArrayUtil { } return result; } - + public static int hasDuplicates(long[] array) { for (int i = 0; i < array.length; ++i) { long a = array[i]; @@ -185,10 +185,10 @@ public class ArrayUtil { } } } - + return -1; } - + public static int firstIndexOf(float[] array, float element) { for (int i = 0; i < array.length; ++i) { if (array[i] == element) { @@ -197,7 +197,7 @@ public class ArrayUtil { } return -1; } - + public static int lastIndexOf(float[] array, float element) { for (int i = array.length - 1; i >= 0; --i) { if (array[i] == element) { @@ -206,7 +206,7 @@ public class ArrayUtil { } return -1; } - + public static int occurences(float[] array, float element) { int result = 0; for (int i = 0; i < array.length; ++i) { @@ -216,7 +216,7 @@ public class ArrayUtil { } return result; } - + public static int hasDuplicates(float[] array) { for (int i = 0; i < array.length; ++i) { float a = array[i]; @@ -226,7 +226,7 @@ public class ArrayUtil { } } } - + return -1; } @@ -238,7 +238,7 @@ public class ArrayUtil { } return -1; } - + public static int lastIndexOf(double[] array, double element) { for (int i = array.length - 1; i >= 0; --i) { if (array[i] == element) { @@ -247,7 +247,7 @@ public class ArrayUtil { } return -1; } - + public static int occurences(double[] array, double element) { int result = 0; for (int i = 0; i < array.length; ++i) { @@ -257,7 +257,7 @@ public class ArrayUtil { } return result; } - + public static int hasDuplicates(double[] array) { for (int i = 0; i < array.length; ++i) { double a = array[i]; @@ -267,10 +267,10 @@ public class ArrayUtil { } } } - + return -1; } - + public static int firstIndexOf(boolean[] array, boolean element) { for (int i = 0; i < array.length; ++i) { if (array[i] == element) { @@ -279,7 +279,7 @@ public class ArrayUtil { } return -1; } - + public static int lastIndexOf(boolean[] array, boolean element) { for (int i = array.length - 1; i >= 0; --i) { if (array[i] == element) { @@ -288,7 +288,7 @@ public class ArrayUtil { } return -1; } - + public static int occurences(boolean[] array, boolean element) { int result = 0; for (int i = 0; i < array.length; ++i) { @@ -298,7 +298,7 @@ public class ArrayUtil { } return result; } - + public static int firstIndexOf(char[] array, char element) { for (int i = 0; i < array.length; ++i) { if (array[i] == element) { @@ -307,7 +307,7 @@ public class ArrayUtil { } return -1; } - + public static int lastIndexOf(char[] array, char element) { for (int i = array.length - 1; i >= 0; --i) { if (array[i] == element) { @@ -316,7 +316,7 @@ public class ArrayUtil { } return -1; } - + public static int occurences(char[] array, char element) { int result = 0; for (int i = 0; i < array.length; ++i) { @@ -326,7 +326,7 @@ public class ArrayUtil { } return result; } - + public static int hasDuplicates(char[] array) { for (int i = 0; i < array.length; ++i) { char a = array[i]; @@ -336,10 +336,10 @@ public class ArrayUtil { } } } - + return -1; } - + public static int firstIndexOf(Object[] array, Object element) { for (int i = 0; i < array.length; ++i) { if (array[i] == element) { @@ -348,7 +348,7 @@ public class ArrayUtil { } return -1; } - + public static int lastIndexOf(Object[] array, Object element) { for (int i = array.length - 1; i >= 0; --i) { if (array[i] == element) { @@ -357,7 +357,7 @@ public class ArrayUtil { } return -1; } - + public static int occurences(Object[] array, Object element) { int result = 0; for (int i = 0; i < array.length; ++i) { @@ -367,7 +367,7 @@ public class ArrayUtil { } return result; } - + public static int hasDuplicates(Object[] array) { for (int i = 0; i < array.length; ++i) { Object a = array[i]; @@ -377,10 +377,10 @@ public class ArrayUtil { } } } - + return -1; } - + public static int firstIndexOfEqual(Object[] array, Object element) { for (int i = 0; i < array.length; ++i) { if (Objects.equals(array[i], element)) { @@ -389,7 +389,7 @@ public class ArrayUtil { } return -1; } - + public static int lastIndexOfEqual(Object[] array, Object element) { for (int i = array.length - 1; i >= 0; --i) { if (Objects.equals(array[i], element)) { @@ -398,7 +398,7 @@ public class ArrayUtil { } return -1; } - + public static int occurencesOfEqual(Object[] array, Object element) { int result = 0; for (int i = 0; i < array.length; ++i) { @@ -408,7 +408,7 @@ public class ArrayUtil { } return result; } - + public static int hasEquals(Object[] array) { for (int i = 0; i < array.length; ++i) { Object a = array[i]; @@ -418,10 +418,10 @@ public class ArrayUtil { } } } - + return -1; } - + public static long sum(byte[] array, int start, int length) { long s = 0; length += start; @@ -430,7 +430,7 @@ public class ArrayUtil { } return s; } - + public static long sum(short[] array, int start, int length) { long s = 0; length += start; @@ -439,7 +439,7 @@ public class ArrayUtil { } return s; } - + public static long sum(int[] array, int start, int length) { long s = 0; length += start; @@ -448,7 +448,7 @@ public class ArrayUtil { } return s; } - + public static long sum(long[] array, int start, int length) { long s = 0; length += start; @@ -457,7 +457,7 @@ public class ArrayUtil { } return s; } - + public static BigInteger longSum(long[] array, int start, int length) { BigInteger s = BigInteger.ZERO; length += start; @@ -466,7 +466,7 @@ public class ArrayUtil { } return s; } - + public static float sum(float[] array, int start, int length) { float s = 0; length += start; @@ -475,7 +475,7 @@ public class ArrayUtil { } return s; } - + public static double sum(double[] array, int start, int length) { double s = 0; length += start; @@ -484,7 +484,7 @@ public class ArrayUtil { } return s; } - + public static long sum(char[] array, int start, int length) { long s = 0; length += start; @@ -493,33 +493,35 @@ public class ArrayUtil { } return s; } - + public static int checkArrayOffsetLength(Object array, int offset, int length) { int arrayLength = Array.getLength(array); - + if (length < 0) length = arrayLength; - + int end = offset + length; if (end > arrayLength || offset < 0) - throw new IllegalArgumentException("Array contains [0; " + arrayLength + "), requested [" + offset + "; " + end + ")"); - + throw new IllegalArgumentException( + "Array contains [0; " + arrayLength + "), requested [" + offset + "; " + end + ")"); + return length; } - + public static int checkArrayStartEnd(Object array, int start, int end) { int arrayLength = Array.getLength(array); - + if (end < 0) end = arrayLength; - + if (start > end) throw new IllegalArgumentException("Start > end: " + start + " > " + end); - + if (end > arrayLength || start < 0) - throw new IllegalArgumentException("Array contains [0; " + arrayLength + "), requested [" + start + "; " + end + ")"); - + throw new IllegalArgumentException( + "Array contains [0; " + arrayLength + "), requested [" + start + "; " + end + ")"); + return end; } - + } diff --git a/src/main/java/ru/windcorp/progressia/client/ClientProxy.java b/src/main/java/ru/windcorp/progressia/client/ClientProxy.java index 9690642..921fce5 100644 --- a/src/main/java/ru/windcorp/progressia/client/ClientProxy.java +++ b/src/main/java/ru/windcorp/progressia/client/ClientProxy.java @@ -26,6 +26,7 @@ import ru.windcorp.progressia.client.graphics.font.Typefaces; import ru.windcorp.progressia.client.graphics.texture.Atlases; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.common.resource.ResourceManager; +import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.server.ServerState; import ru.windcorp.progressia.test.TestContent; @@ -39,8 +40,7 @@ public class ClientProxy implements Proxy { RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init); RenderTaskQueue.waitAndInvoke(() -> Typefaces.setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz")))); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + CrashReports.report(e, "ClientProxy failed"); } TestContent.registerContent(); diff --git a/src/main/java/ru/windcorp/progressia/client/ProgressiaClientMain.java b/src/main/java/ru/windcorp/progressia/client/ProgressiaClientMain.java index bc79991..0b755f0 100644 --- a/src/main/java/ru/windcorp/progressia/client/ProgressiaClientMain.java +++ b/src/main/java/ru/windcorp/progressia/client/ProgressiaClientMain.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.client; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import ru.windcorp.progressia.ProgressiaLauncher; -import ru.windcorp.progressia.common.util.crash.CrashReportGenerator; +import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer; import ru.windcorp.progressia.common.util.crash.providers.OSContextProvider; @@ -31,17 +31,16 @@ public class ProgressiaClientMain { public static void main(String[] args) { logger.info("App started!"); - CrashReportGenerator.registerProvider(new OSContextProvider()); - CrashReportGenerator.registerAnalyzer(new OutOfMemoryAnalyzer()); + CrashReports.registerProvider(new OSContextProvider()); + CrashReports.registerAnalyzer(new OutOfMemoryAnalyzer()); try { @SuppressWarnings("unused") long[] ssdss = new long[1 << 30]; - } catch (Throwable t) - { - CrashReportGenerator.crash(t, "u %s stupid", "vry"); + } catch (Throwable t) { + CrashReports.report(t, "u %s stupid", "vry"); } ProgressiaLauncher.launch(args, new ClientProxy()); } - -} + +} \ No newline at end of file diff --git a/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java b/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java index 4292bb9..b2c7051 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java @@ -8,12 +8,13 @@ import ru.windcorp.progressia.common.comms.CommsListener; import ru.windcorp.progressia.common.comms.packets.Packet; import ru.windcorp.progressia.common.comms.packets.PacketSetLocalPlayer; import ru.windcorp.progressia.common.comms.packets.PacketWorldChange; +import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.PacketEntityChange; // TODO refactor with no mercy public class DefaultClientCommsListener implements CommsListener { - + private final Client client; public DefaultClientCommsListener(Client client) { @@ -41,9 +42,9 @@ public class DefaultClientCommsListener implements CommsListener { ); if (entity == null) { - throw new RuntimeException(""); + CrashReports.report(null, "Player entity not found"); } - + getClient().setLocalPlayer(entity); getClient().getCamera().setAnchor(new EntityAnchor( getClient().getWorld().getEntityRenderable(entity) @@ -58,7 +59,7 @@ public class DefaultClientCommsListener implements CommsListener { public void onIOError(IOException reason) { // TODO implement } - + public Client getClient() { return client; } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Program.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Program.java index 6aee18d..64c54bc 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Program.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Program.java @@ -24,37 +24,38 @@ import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable; import ru.windcorp.progressia.client.graphics.backend.shaders.attributes.Attribute; import ru.windcorp.progressia.client.graphics.backend.shaders.uniforms.Uniform; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class Program implements OpenGLDeletable { - + private int handle; - + public Program(Shader vertexShader, Shader fragmentShader) { handle = glCreateProgram(); OpenGLObjectTracker.register(this); - + glAttachShader(handle, vertexShader.getHandle()); glAttachShader(handle, fragmentShader.getHandle()); - + glLinkProgram(handle); - + if (glGetProgrami(handle, GL_LINK_STATUS) == GL_FALSE) { - throw new RuntimeException("Bad program:\n" + glGetProgramInfoLog(handle)); + CrashReports.report(null, "Bad program:\n %s", glGetProgramInfoLog(handle)); } } - + public Attribute getAttribute(String name) { return new Attribute(glGetAttribLocation(handle, name), this); } - + public Uniform getUniform(String name) { return new Uniform(glGetUniformLocation(handle, name), this); } - + public void use() { glUseProgram(handle); } - + @Override public void delete() { glDeleteProgram(handle); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Shader.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Shader.java index 7dfef92..27567e7 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Shader.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Shader.java @@ -26,26 +26,26 @@ import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable; import ru.windcorp.progressia.common.resource.Resource; import ru.windcorp.progressia.common.resource.ResourceManager; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class Shader implements OpenGLDeletable { - + public static enum ShaderType { - VERTEX(GL_VERTEX_SHADER), - FRAGMENT(GL_FRAGMENT_SHADER); - + VERTEX(GL_VERTEX_SHADER), FRAGMENT(GL_FRAGMENT_SHADER); + private final int glCode; - + private ShaderType(int glCode) { this.glCode = glCode; } - + public int getGlCode() { return glCode; } - + public static ShaderType guessByResourceName(String resource) { resource = resource.toLowerCase(Locale.ENGLISH); - + if (resource.contains("vertex")) return VERTEX; if (resource.contains("fragment")) return FRAGMENT; if (resource.contains("vsh")) return VERTEX; @@ -57,48 +57,48 @@ public class Shader implements OpenGLDeletable { ); } } - + private static final String SHADER_ASSETS_PREFIX = "assets/shaders/"; - + protected static Resource getShaderResource(String name) { return ResourceManager.getResource(SHADER_ASSETS_PREFIX + name); } - + private final int handle; private final ShaderType type; - + public Shader(ShaderType type, String source) { handle = glCreateShader(type.getGlCode()); OpenGLObjectTracker.register(this); - + this.type = type; - + glShaderSource(handle, source); glCompileShader(handle); - + if (glGetShaderi(handle, GL_COMPILE_STATUS) == GL_FALSE) { System.out.println("***************** ERROR ******************"); System.out.println(source); - throw new RuntimeException("Bad shader:\n" + glGetShaderInfoLog(handle)); + CrashReports.report(null, "Bad shader:\n %s", glGetShaderInfoLog(handle)); } } - + public Shader(String resource) { this( ShaderType.guessByResourceName(resource), getShaderResource(resource).readAsString() ); } - + @Override public void delete() { glDeleteShader(handle); } - + public int getHandle() { return handle; } - + public ShaderType getType() { return type; } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/Attribute.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/Attribute.java index 3773d18..34624f4 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/Attribute.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/Attribute.java @@ -18,29 +18,30 @@ package ru.windcorp.progressia.client.graphics.backend.shaders.attributes; import ru.windcorp.progressia.client.graphics.backend.shaders.Program; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class Attribute { - + protected final int handle; private final Program program; - + public Attribute(int handle, Program program) { if (handle < 0) { - throw new RuntimeException("Bad handle: " + handle); + CrashReports.report(null, "Bad handle: %s", handle); } - + this.handle = handle; this.program = program; } - + public int getHandle() { return handle; } - + public Program getProgram() { return program; } - + public AttributeVertexArray asVertexArray() { return new AttributeVertexArray(handle, program); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform.java index be78878..d1475b0 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform.java @@ -18,69 +18,70 @@ package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import ru.windcorp.progressia.client.graphics.backend.shaders.Program; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class Uniform { - + protected final int handle; private final Program program; - + public Uniform(int handle, Program program) { if (handle < 0) { - throw new RuntimeException("Bad handle: " + handle); + CrashReports.report(null, "Bad handle: %s", handle); } - + this.handle = handle; this.program = program; } - + public int getHandle() { return handle; } - + public Program getProgram() { return program; } - + public Uniform1Float as1Float() { return new Uniform1Float(handle, program); } - + public Uniform1Int as1Int() { return new Uniform1Int(handle, program); } - + public Uniform2Float as2Float() { return new Uniform2Float(handle, program); } - + public Uniform2Int as2Int() { return new Uniform2Int(handle, program); } - + public Uniform3Float as3Float() { return new Uniform3Float(handle, program); } - + public Uniform3Int as3Int() { return new Uniform3Int(handle, program); } - + public Uniform4Float as4Float() { return new Uniform4Float(handle, program); } - + public Uniform4Int as4Int() { return new Uniform4Int(handle, program); } - + public Uniform2Matrix as2Matrix() { return new Uniform2Matrix(handle, program); } - + public Uniform3Matrix as3Matrix() { return new Uniform3Matrix(handle, program); } - + public Uniform4Matrix as4Matrix() { return new Uniform4Matrix(handle, program); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifontLoader.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifontLoader.java index 681effb..61e9666 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifontLoader.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifontLoader.java @@ -21,117 +21,96 @@ import ru.windcorp.progressia.client.graphics.texture.Texture; import ru.windcorp.progressia.client.graphics.texture.TextureDataEditor; import ru.windcorp.progressia.client.graphics.texture.TextureSettings; import ru.windcorp.progressia.common.resource.Resource; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class GNUUnifontLoader { - - private static final AtlasGroup ATLAS_GROUP_GNU_UNIFONT = - new AtlasGroup("GNUUnifont", 1 << 12); - - private static final TextureSettings TEXTURE_SETTINGS = - new TextureSettings(false); - + + private static final AtlasGroup ATLAS_GROUP_GNU_UNIFONT = new AtlasGroup("GNUUnifont", 1 << 12); + + private static final TextureSettings TEXTURE_SETTINGS = new TextureSettings(false); + private static final int BITS_PER_HEX_DIGIT = 4; private static final int PREFIX_LENGTH = "0000:".length(); - + private static class ParsedGlyph { final char c; final TextureDataEditor data; - + ParsedGlyph(char c, TextureDataEditor data) { this.c = c; this.data = data; } } - + private static class AtlasGlyph { final char c; final Texture texture; - + AtlasGlyph(char c, Texture texture) { this.c = c; this.texture = texture; } } - + public static GNUUnifont load(Resource resource) { try (BufferedReader reader = createReader(resource)) { - return createStream(reader) - .map(GNUUnifontLoader::parse) - .map(GNUUnifontLoader::addToAtlas) - .collect(Collectors.collectingAndThen( - createMapper(), - GNUUnifont::new - )); + return createStream(reader).map(GNUUnifontLoader::parse).map(GNUUnifontLoader::addToAtlas) + .collect(Collectors.collectingAndThen(createMapper(), GNUUnifont::new)); } catch (IOException | UncheckedIOException e) { - throw new RuntimeException(e); + CrashReports.report(e, "Problem with load GNUUnifont"); + return null; } } - - private static BufferedReader createReader(Resource resource) - throws IOException - { + + private static BufferedReader createReader(Resource resource) throws IOException { return new BufferedReader( - new InputStreamReader( - new GZIPInputStream( - resource.getInputStream() - ), - StandardCharsets.UTF_8 - ) - ); + new InputStreamReader(new GZIPInputStream(resource.getInputStream()), StandardCharsets.UTF_8)); } private static Stream createStream(BufferedReader reader) { return reader.lines(); } - + private static ParsedGlyph parse(String declar) { int width = getWidth(declar); checkDeclaration(declar, width); - + char c = getChar(declar); - - TextureDataEditor editor = new TextureDataEditor( - width, GNUUnifont.HEIGHT, - width, GNUUnifont.HEIGHT, - TEXTURE_SETTINGS - ); - + + TextureDataEditor editor = new TextureDataEditor(width, GNUUnifont.HEIGHT, width, GNUUnifont.HEIGHT, + TEXTURE_SETTINGS); + for (int y = 0; y < GNUUnifont.HEIGHT; ++y) { for (int x = 0; x < width; ++x) { int bit = x + y * width; - - editor.setPixel( - x, GNUUnifont.HEIGHT - y - 1, - getBit(declar, bit) ? 0xFFFFFFFF : 0x00000000 - ); + + editor.setPixel(x, GNUUnifont.HEIGHT - y - 1, getBit(declar, bit) ? 0xFFFFFFFF : 0x00000000); } } - + return new ParsedGlyph(c, editor); } - + private static char getChar(String declar) { int result = 0; - + for (int i = 0; i < 4; ++i) { - result = - (result << BITS_PER_HEX_DIGIT) | - getHexValue(declar.charAt(i)); + result = (result << BITS_PER_HEX_DIGIT) | getHexValue(declar.charAt(i)); } - + return (char) result; } private static boolean getBit(String declar, int bit) { int character = PREFIX_LENGTH + (bit / BITS_PER_HEX_DIGIT); bit = bit % BITS_PER_HEX_DIGIT; - + char c = declar.charAt(character); int value = getHexValue(c); - + return (value & (1 << (BITS_PER_HEX_DIGIT - bit - 1))) != 0; } - + private static int getWidth(String declar) { int meaningfulChars = declar.length() - PREFIX_LENGTH; final int charsPerColumn = GNUUnifont.HEIGHT / BITS_PER_HEX_DIGIT; @@ -140,33 +119,38 @@ public class GNUUnifontLoader { private static void checkDeclaration(String declar, int width) { if (!GNUUnifont.WIDTHS.contains(width)) { - throw new RuntimeException("Width " + width + " is not supported (in declar \"" + declar + "\")"); + CrashReports.report(null, "Width %d is not supported (in declar \"%s\")", width, declar); } - + if ((declar.length() - PREFIX_LENGTH) % width != 0) { - throw new RuntimeException("Declar \"" + declar + "\" has invalid length"); + CrashReports.report(null, "Declar \"%s\" has invalid length", declar); } - + for (int i = 0; i < declar.length(); ++i) { if (i == BITS_PER_HEX_DIGIT) { if (declar.charAt(i) != ':') { - throw new RuntimeException("No colon ':' found in declar \"" + declar + "\" at index 4"); + CrashReports.report(null, "No colon ':' found in declar \"%s\" at index 4", declar); } } else { char c = declar.charAt(i); - + if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))) { - throw new RuntimeException("Illegal char in declar \"" + declar + "\" at index " + i + "; expected 0-9A-F"); + CrashReports.report(null, + "Illegal char in declar \"%s\" at index " + i + "; expected 0-9A-F", declar); } } } } - + private static int getHexValue(char digit) { - if (digit < '0') throw new NumberFormatException(digit + " is not a hex digit (0-9A-F expected)"); - if (digit <= '9') return digit - '0'; - if (digit < 'A') throw new NumberFormatException(digit + " is not a hex digit (0-9A-F expected)"); - if (digit <= 'F') return digit - 'A' + 0xA; + if (digit < '0') + throw new NumberFormatException(digit + " is not a hex digit (0-9A-F expected)"); + if (digit <= '9') + return digit - '0'; + if (digit < 'A') + throw new NumberFormatException(digit + " is not a hex digit (0-9A-F expected)"); + if (digit <= 'F') + return digit - 'A' + 0xA; throw new NumberFormatException(digit + " is not a hex digit (0-9A-F expected)"); } @@ -174,24 +158,21 @@ public class GNUUnifontLoader { Sprite sprite = Atlases.loadSprite(glyph.data.getData(), ATLAS_GROUP_GNU_UNIFONT); return new AtlasGlyph(glyph.c, new SimpleTexture(sprite)); } - - private static - Collector> - createMapper() { - return Collector.of( - TCharObjectHashMap::new, - + + private static Collector> createMapper() { + return Collector.of(TCharObjectHashMap::new, + (map, glyph) -> map.put(glyph.c, glyph.texture), - + (a, b) -> { a.putAll(b); return a; }, - - Characteristics.UNORDERED - ); + + Characteristics.UNORDERED); } - private GNUUnifontLoader() {} + private GNUUnifontLoader() { + } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java index 9260476..7ba1b83 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java @@ -39,40 +39,40 @@ import ru.windcorp.progressia.client.graphics.input.bus.Input; import ru.windcorp.progressia.client.graphics.input.bus.InputBus; import ru.windcorp.progressia.client.graphics.input.bus.InputListener; import ru.windcorp.progressia.common.util.Named; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class Component extends Named { - private final List children = - Collections.synchronizedList(new CopyOnWriteArrayList<>()); - + private final List children = Collections.synchronizedList(new CopyOnWriteArrayList<>()); + private Component parent = null; - + private EventBus eventBus = null; private InputBus inputBus = null; - + private int x, y; private int width, height; - + private boolean valid = false; - + private Vec2i preferredSize = null; - + private Object layoutHint = null; private Layout layout = null; - + private boolean isFocusable = false; private boolean isFocused = false; - + private boolean isHovered = false; public Component(String name) { super(name); } - + public Component getParent() { return parent; } - + protected void setParent(Component parent) { if (this.parent != parent) { Component previousParent = this.parent; @@ -81,68 +81,71 @@ public class Component extends Named { dispatchEvent(new ParentChangedEvent(this, previousParent, parent)); } } - + public List getChildren() { return children; } - + public Component getChild(int index) { synchronized (getChildren()) { - if (index < 0 || index >= getChildren().size()) return null; + if (index < 0 || index >= getChildren().size()) + return null; return getChildren().get(index); } } - + public int getChildIndex(Component child) { return getChildren().indexOf(child); } - + public int getOwnIndex() { Component parent = getParent(); if (parent != null) { return parent.getChildIndex(this); } - + return -1; } - + public void moveChild(Component child, int newIndex) { - if (newIndex == -1) newIndex = getChildren().size() - 1; - + if (newIndex == -1) + newIndex = getChildren().size() - 1; + if (getChildren().remove(child)) { getChildren().add(newIndex, child); invalidate(); } } - + public void moveSelf(int newIndex) { Component parent = getParent(); if (parent != null) { parent.moveChild(this, newIndex); } } - + public Component addChild(Component child, int index) { - if (index == -1) index = getChildren().size(); + if (index == -1) + index = getChildren().size(); invalidate(); getChildren().add(index, child); child.setParent(this); - + dispatchEvent(new ChildAddedEvent(this, child)); - + return this; } - + public Component addChild(Component child) { return addChild(child, -1); } - + public Component removeChild(Component child) { if (!getChildren().contains(child)) { return this; } - + if (child.isFocused()) { child.focusNext(); } @@ -150,204 +153,205 @@ public class Component extends Named { invalidate(); getChildren().remove(child); child.setParent(null); - + dispatchEvent(new ChildRemovedEvent(this, child)); - + return this; } - + public synchronized int getX() { return x; } - + public synchronized int getY() { return y; } - + public synchronized Component setPosition(int x, int y) { invalidate(); this.x = x; this.y = y; return this; } - + public synchronized int getWidth() { return width; } - + public synchronized int getHeight() { return height; } - + public synchronized Component setSize(int width, int height) { invalidate(); this.width = width; this.height = height; return this; } - + public Component setSize(Vec2i size) { return setSize(size.x, size.y); } - + public synchronized Component setBounds(int x, int y, int width, int height) { setPosition(x, y); setSize(width, height); return this; } - + public Component setBounds(int x, int y, Vec2i size) { return setBounds(x, y, size.x, size.y); } - + public boolean isValid() { return valid; } - + public synchronized void invalidate() { valid = false; getChildren().forEach(child -> child.invalidate()); } - + public synchronized void validate() { Component parent = getParent(); invalidate(); - + if (parent == null) { layoutSelf(); } else { parent.validate(); } } - + protected synchronized void layoutSelf() { try { if (getLayout() != null) { getLayout().layout(this); } - + getChildren().forEach(child -> { child.layoutSelf(); }); - + valid = true; } catch (Exception e) { - throw new RuntimeException(e); + CrashReports.report(e, "__DOC__ME__"); } } - + public synchronized Vec2i getPreferredSize() { if (preferredSize != null) { return preferredSize; } - + if (getLayout() != null) { try { return getLayout().calculatePreferredSize(this); } catch (Exception e) { - throw new RuntimeException(e); + CrashReports.report(e, "__DOC__ME__"); } } - + return new Vec2i(0, 0); } - + public synchronized Component setPreferredSize(Vec2i preferredSize) { this.preferredSize = preferredSize; return this; } - + public Component setPreferredSize(int width, int height) { return setPreferredSize(new Vec2i(width, height)); } - + public Layout getLayout() { return layout; } - + public synchronized Component setLayout(Layout layout) { invalidate(); this.layout = layout; return this; } - + public Object getLayoutHint() { return layoutHint; } - + public Component setLayoutHint(Object hint) { this.layoutHint = hint; return this; } - + public boolean isFocusable() { return isFocusable; } - + public Component setFocusable(boolean focusable) { this.isFocusable = focusable; return this; } - + public boolean isFocused() { return isFocused; } - + protected synchronized void setFocused(boolean focus) { if (focus != this.isFocused) { dispatchEvent(new FocusEvent(this, focus)); this.isFocused = focus; } } - + public Component takeFocus() { if (isFocused()) { return this; } - + Component comp = this; Component focused = null; - + while (comp != null) { if ((focused = comp.findFocused()) != null) { focused.setFocused(false); setFocused(true); return this; } - + comp = comp.getParent(); } - + setFocused(true); return this; } - + public void focusNext() { Component component = this; - + while (true) { - + component = component.getNextFocusCandidate(true); if (component == this) { return; } - + if (component.isFocusable()) { setFocused(false); component.setFocused(true); return; } - + } } - + private Component getNextFocusCandidate(boolean canUseChildren) { - if (canUseChildren) synchronized (getChildren()) { - if (!getChildren().isEmpty()) { - return getChild(0); + if (canUseChildren) + synchronized (getChildren()) { + if (!getChildren().isEmpty()) { + return getChild(0); + } } - } - + Component parent = getParent(); if (parent != null) { synchronized (parent.getChildren()) { @@ -356,32 +360,32 @@ public class Component extends Named { return parent.getChild(ownIndex + 1); } } - + return parent.getNextFocusCandidate(false); } - + return this; } - + public void focusPrevious() { Component component = this; - + while (true) { - + component = component.getPreviousFocusCandidate(); if (component == this) { return; } - + if (component.isFocusable()) { setFocused(false); component.setFocused(true); return; } - + } } - + private Component getPreviousFocusCandidate() { Component parent = getParent(); if (parent != null) { @@ -391,30 +395,30 @@ public class Component extends Named { return parent.getChild(ownIndex - 1).getLastDeepChild(); } } - + return parent; } - + return getLastDeepChild(); } - + private Component getLastDeepChild() { synchronized (getChildren()) { if (!getChildren().isEmpty()) { return getChild(getChildren().size() - 1).getLastDeepChild(); } - + return this; } } - + public synchronized Component findFocused() { if (isFocused()) { return this; } - + Component result; - + synchronized (getChildren()) { for (Component c : getChildren()) { result = c.findFocused(); @@ -423,10 +427,10 @@ public class Component extends Named { } } } - + return null; } - + public boolean isHovered() { return isHovered; } @@ -434,9 +438,9 @@ public class Component extends Named { protected void setHovered(boolean isHovered) { if (this.isHovered != isHovered) { this.isHovered = isHovered; - + if (!isHovered && !getChildren().isEmpty()) { - + getChildren().forEach(child -> { if (child.isHovered()) { child.setHovered(false); @@ -444,7 +448,7 @@ public class Component extends Named { } }); } - + dispatchEvent(new HoverEvent(this, isHovered)); } } @@ -453,40 +457,36 @@ public class Component extends Named { if (eventBus == null) { eventBus = new EventBus(getName()); } - + eventBus.register(listener); } - + public void removeListener(Object listener) { - if (eventBus == null) return; + if (eventBus == null) + return; eventBus.unregister(listener); } - + public void dispatchEvent(Object event) { - if (eventBus == null) return; + if (eventBus == null) + return; eventBus.post(event); } - - public void addListener( - Class type, - boolean handlesConsumed, - InputListener listener - ) { + + public void addListener(Class type, boolean handlesConsumed, + InputListener listener) { if (inputBus == null) { inputBus = new InputBus(); } - + inputBus.register(type, handlesConsumed, listener); } - public void addListener( - Class type, - InputListener listener - ) { + public void addListener(Class type, InputListener listener) { if (inputBus == null) { inputBus = new InputBus(); } - + inputBus.register(type, listener); } @@ -501,43 +501,45 @@ public class Component extends Named { inputBus.dispatch(input); } } - + public void dispatchInput(Input input) { try { switch (input.getTarget()) { - case FOCUSED: - dispatchInputToFocused(input); - break; - case HOVERED: - dispatchInputToHovered(input); - break; - case ALL: - default: - dispatchInputToAll(input); - break; + case FOCUSED: + dispatchInputToFocused(input); + break; + case HOVERED: + dispatchInputToHovered(input); + break; + case ALL: + default: + dispatchInputToAll(input); + break; } } catch (Exception e) { - throw new RuntimeException(e); + CrashReports.report(e, "__DOC__ME__"); } } private void dispatchInputToFocused(Input input) { Component c = findFocused(); - - if (c == null) return; - if (attemptFocusTransfer(input, c)) return; - + + if (c == null) + return; + if (attemptFocusTransfer(input, c)) + return; + while (c != null) { c.handleInput(input); c = c.getParent(); } } - + private void dispatchInputToHovered(Input input) { getChildren().forEach(child -> { if (child.containsCursor()) { child.setHovered(true); - + if (!input.isConsumed()) { child.dispatchInput(input); } @@ -555,11 +557,13 @@ public class Component extends Named { } private boolean attemptFocusTransfer(Input input, Component focused) { - if (input.isConsumed()) return false; - if (!(input.getEvent() instanceof KeyEvent)) return false; - + if (input.isConsumed()) + return false; + if (!(input.getEvent() instanceof KeyEvent)) + return false; + KeyEvent keyInput = (KeyEvent) input.getEvent(); - + if (keyInput.getKey() == GLFW.GLFW_KEY_TAB && !keyInput.isRelease()) { input.consume(); if (keyInput.hasShift()) { @@ -569,23 +573,18 @@ public class Component extends Named { } return true; } - + return false; } - + public synchronized boolean contains(int x, int y) { - return - x >= getX() && x < getX() + getWidth() && - y >= getY() && y < getY() + getHeight(); + return x >= getX() && x < getX() + getWidth() && y >= getY() && y < getY() + getHeight(); } - + public boolean containsCursor() { - return contains( - (int) InputTracker.getCursorX(), - (int) InputTracker.getCursorY() - ); + return contains((int) InputTracker.getCursorX(), (int) InputTracker.getCursorY()); } - + public void requestReassembly() { if (parent != null) { parent.requestReassembly(); @@ -602,60 +601,60 @@ public class Component extends Named { if (width == 0 || height == 0) { return; } - + if (!isValid()) { validate(); } - + try { assembleSelf(target); } catch (Exception e) { - throw new RuntimeException(e); + CrashReports.report(e, "__DOC__ME__"); } - + assembleChildren(target); - + try { postAssembleSelf(target); } catch (Exception e) { - throw new RuntimeException(e); + CrashReports.report(e, "__DOC__ME__"); } } - + protected void assembleSelf(RenderTarget target) { // To be overridden } - + protected void postAssembleSelf(RenderTarget target) { // To be overridden } - + protected void assembleChildren(RenderTarget target) { getChildren().forEach(child -> child.assemble(target)); } - -// /** -// * Returns a component that displays this component in its center. -// * @return a {@link Aligner} initialized to center this component -// */ -// public Component center() { -// return new Aligner(this); -// } -// -// /** -// * Returns a component that aligns this component. -// * @return a {@link Aligner} initialized with this component -// */ -// public Component align(double x, double y) { -// return new Aligner(this, x, y); -// } -// -// /** -// * Returns a component that allows scrolling this component -// * @return a {@link Scroller} initialized with this component -// */ -// public Component scroller() { -// return new Scroller(this); -// } + + // /** + // * Returns a component that displays this component in its center. + // * @return a {@link Aligner} initialized to center this component + // */ + // public Component center() { + // return new Aligner(this); + // } + // + // /** + // * Returns a component that aligns this component. + // * @return a {@link Aligner} initialized with this component + // */ + // public Component align(double x, double y) { + // return new Aligner(this, x, y); + // } + // + // /** + // * Returns a component that allows scrolling this component + // * @return a {@link Scroller} initialized with this component + // */ + // public Component scroller() { + // return new Scroller(this); + // } } \ No newline at end of file diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/Keys.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/Keys.java index c080192..f97c4b0 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/Keys.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/Keys.java @@ -31,108 +31,101 @@ import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.map.hash.TObjectIntHashMap; import gnu.trove.set.TIntSet; import gnu.trove.set.hash.TIntHashSet; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class Keys { - - private static final TIntObjectMap CODES_TO_NAMES = - new TIntObjectHashMap<>(); - - private static final TObjectIntMap NAMES_TO_CODES = - new TObjectIntHashMap<>(); - + + private static final TIntObjectMap CODES_TO_NAMES = new TIntObjectHashMap<>(); + + private static final TObjectIntMap NAMES_TO_CODES = new TObjectIntHashMap<>(); + private static final TIntSet MOUSE_BUTTONS = new TIntHashSet(); - + private static final String KEY_PREFIX = "GLFW_KEY_"; private static final String MOUSE_BUTTON_PREFIX = "GLFW_MOUSE_BUTTON_"; - - private static final Set IGNORE_FIELDS = - new HashSet<>(Arrays.asList( - "GLFW_KEY_UNKNOWN", - "GLFW_KEY_LAST", - "GLFW_MOUSE_BUTTON_LAST", - "GLFW_MOUSE_BUTTON_1", // Alias for LEFT + + private static final Set IGNORE_FIELDS = new HashSet<>( + Arrays.asList("GLFW_KEY_UNKNOWN", "GLFW_KEY_LAST", "GLFW_MOUSE_BUTTON_LAST", "GLFW_MOUSE_BUTTON_1", // Alias + // for + // LEFT "GLFW_MOUSE_BUTTON_2", // Alias for RIGHT - "GLFW_MOUSE_BUTTON_3" // Alias for MIDDLE + "GLFW_MOUSE_BUTTON_3" // Alias for MIDDLE )); - + static { initializeDictionary(); } private static void initializeDictionary() { try { - + for (Field field : GLFW.class.getFields()) { - if (!Modifier.isStatic(field.getModifiers())) continue; - if (!Modifier.isFinal(field.getModifiers())) continue; - + if (!Modifier.isStatic(field.getModifiers())) + continue; + if (!Modifier.isFinal(field.getModifiers())) + continue; + String name = field.getName(); - - if ( - !name.startsWith(KEY_PREFIX) && - !name.startsWith(MOUSE_BUTTON_PREFIX) - ) continue; - - if (IGNORE_FIELDS.contains(name)) continue; - + + if (!name.startsWith(KEY_PREFIX) && !name.startsWith(MOUSE_BUTTON_PREFIX)) + continue; + + if (IGNORE_FIELDS.contains(name)) + continue; + addToDictionary(field); } - + } catch (IllegalAccessException e) { - throw new RuntimeException(e); + CrashReports.report(e, "Cannot access GLFW constants"); } } - private static void addToDictionary(Field field) - throws IllegalAccessException { - + private static void addToDictionary(Field field) throws IllegalAccessException { + int value = field.getInt(null); String name = field.getName(); - + if (name.startsWith(KEY_PREFIX)) { name = name.substring(KEY_PREFIX.length()); } else if (name.startsWith(MOUSE_BUTTON_PREFIX)) { name = "MOUSE_" + name.substring(MOUSE_BUTTON_PREFIX.length()); MOUSE_BUTTONS.add(value); } - + if (CODES_TO_NAMES.containsKey(value)) { - throw new RuntimeException( - "Duplicate keys: " + CODES_TO_NAMES.get(value) + - " and " + name + " both map to " + value + - "(0x" + Integer.toHexString(value) + ")" - ); + CrashReports.report(null, "Duplicate keys: %s and %s both map to %d(0x%s)", + CODES_TO_NAMES.get(value), name, value, Integer.toHexString(value)); } - + CODES_TO_NAMES.put(value, name); NAMES_TO_CODES.put(name, value); } - + public static String getInternalName(int code) { String result = CODES_TO_NAMES.get(code); - + if (result == null) { return "UNKNOWN"; } - + return result; } - + public static String getDisplayName(int code) { String name = getInternalName(code); - + if (name.startsWith("KP_")) { name = "KEYPAD_" + name.substring("KP_".length()); } - - name = Character.toTitleCase(name.charAt(0)) + - name.substring(1).toLowerCase(); - + + name = Character.toTitleCase(name.charAt(0)) + name.substring(1).toLowerCase(); + name = name.replace('_', ' '); - + return name; } - + public static int getCode(String internalName) { if (NAMES_TO_CODES.containsKey(internalName)) { return -1; @@ -140,7 +133,7 @@ public class Keys { return NAMES_TO_CODES.get(internalName); } } - + public static boolean isMouse(int code) { return MOUSE_BUTTONS.contains(code); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/Atlases.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/Atlases.java index 0d7c435..a945f03 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/Atlases.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/Atlases.java @@ -13,72 +13,67 @@ import ru.windcorp.progressia.client.graphics.backend.RenderTaskQueue; import ru.windcorp.progressia.common.resource.Resource; import ru.windcorp.progressia.common.util.BinUtil; import ru.windcorp.progressia.common.util.Named; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class Atlases { - + public static class AtlasGroup extends Named { private final int atlasSize; - + public AtlasGroup(String name, int atlasSize) { super(name); this.atlasSize = atlasSize; - + if (!BinUtil.isPowerOf2(atlasSize)) { - throw new IllegalArgumentException( - "Atlas size " + atlasSize - + " is not a power of 2" - ); + throw new IllegalArgumentException("Atlas size " + atlasSize + " is not a power of 2"); } } - + public int getAtlasSize() { return atlasSize; } - + @Override public int hashCode() { return super.hashCode(); } - + @Override public boolean equals(Object obj) { return super.equals(obj); } } - + public static class Atlas { private final AtlasGroup group; - + private final TextureDataEditor editor; private int nextX, nextY; private int rowHeight; - + private final TexturePrimitive primitive; - + public Atlas(AtlasGroup group) { this.group = group; int size = group.getAtlasSize(); - + this.editor = new TextureDataEditor(size, size, size, size, SETTINGS); this.primitive = new TexturePrimitive(editor.getData()); } - + public Sprite addSprite(TextureData data) { int width = data.getContentWidth(); int height = data.getContentHeight(); - + selectPosition(width, height); - + editor.draw(data, nextX, nextY); - - Sprite result = new Sprite( - getPrimitive(), - toPrimitiveCoords(nextX, nextY), - toPrimitiveCoords(width, height) - ); - + + Sprite result = new Sprite(getPrimitive(), toPrimitiveCoords(nextX, nextY), + toPrimitiveCoords(width, height)); + nextX += width; - + return result; } @@ -87,10 +82,10 @@ public class Atlases { // Wrapping nextY += rowHeight; // Move to next row rowHeight = height; // Next row is at least 'height' high - nextX = 0; // Start the row over + nextX = 0; // Start the row over } else { // Not wrapping - + // Update rowHeight if necessary if (rowHeight < height) { rowHeight = height; @@ -99,10 +94,7 @@ public class Atlases { } private Vec2 toPrimitiveCoords(int x, int y) { - return new Vec2( - toPrimitiveCoord(x), - toPrimitiveCoord(y) - ); + return new Vec2(toPrimitiveCoord(x), toPrimitiveCoord(y)); } private float toPrimitiveCoord(int c) { @@ -112,87 +104,82 @@ public class Atlases { public boolean canAddSprite(TextureData data) { int width = data.getContentWidth(); int height = data.getContentHeight(); - + // Try to fit without wrapping - + if (nextY + height > getSize()) // Does not fit vertically return false; - + if (nextX + width <= getSize()) // Can place at (nextX; nextY) return true; - + // Try wrapping - + if (width > getSize()) // GTFO. We couldn't fit if if we tried return false; - + if (nextY + rowHeight + height > getSize()) // Does not fit vertically when wrapped return false; - + // Can place at (0; nextY + rowHeight) return true; } - + public AtlasGroup getGroup() { return group; } - + public TexturePrimitive getPrimitive() { return primitive; } - + public int getSize() { return editor.getBufferWidth(); } } - + private static final TextureSettings SETTINGS = new TextureSettings(false); - - private static final Map LOADED = - new HashMap<>(); - private static final Multimap ATLASES = - MultimapBuilder.hashKeys().arrayListValues().build(); - + + private static final Map LOADED = new HashMap<>(); + private static final Multimap ATLASES = MultimapBuilder.hashKeys().arrayListValues().build(); + public static Sprite getSprite(Resource resource, AtlasGroup group) { return LOADED.computeIfAbsent(resource, k -> loadSprite(k, group)); } - + private static Sprite loadSprite(Resource resource, AtlasGroup group) { try { - TextureDataEditor data = - TextureLoader.loadPixels(resource, SETTINGS); - + TextureDataEditor data = TextureLoader.loadPixels(resource, SETTINGS); + return loadSprite(data.getData(), group); } catch (IOException e) { - throw new RuntimeException(e); + CrashReports.report(e, "Problem with load atlases sprite"); + return null; } } - + public static Sprite loadSprite(TextureData data, AtlasGroup group) { Atlas atlas = getReadyAtlas(group, data); return atlas.addSprite(data); } - + private static Atlas getReadyAtlas(AtlasGroup group, TextureData data) { List atlases = (List) ATLASES.get(group); - - if ( - atlases.isEmpty() || - !(atlases.get(atlases.size() - 1).canAddSprite(data)) - ) { + + if (atlases.isEmpty() || !(atlases.get(atlases.size() - 1).canAddSprite(data))) { Atlas newAtlas = new Atlas(group); - + if (!newAtlas.canAddSprite(data)) { - throw new RuntimeException("Could not fit tex into atlas of size " + newAtlas.getSize()); + CrashReports.report(null, "Could not fit tex into atlas of size %d", newAtlas.getSize()); } - + atlases.add(newAtlas); } - + return atlases.get(atlases.size() - 1); } @@ -201,7 +188,8 @@ public class Atlases { RenderTaskQueue.invokeLater(atlas.getPrimitive()::load); }); } - - private Atlases() {} + + private Atlases() { + } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTextures.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTextures.java index e453ff7..e0711db 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTextures.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTextures.java @@ -6,21 +6,22 @@ import java.util.Map; import ru.windcorp.progressia.common.resource.Resource; import ru.windcorp.progressia.common.resource.ResourceManager; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class SimpleTextures { - + private static final TextureSettings SETTINGS = new TextureSettings(false); - + private static final Map TEXTURES = new HashMap<>(); - + public static Texture get(Resource resource) { return TEXTURES.computeIfAbsent(resource, SimpleTextures::load); } - + public static Texture get(String textureName) { return get(ResourceManager.getTextureResource(textureName)); } - + private static Texture load(Resource resource) { try { TextureDataEditor data = @@ -30,9 +31,10 @@ public class SimpleTextures { new Sprite(new TexturePrimitive(data.getData())) ); } catch (IOException e) { - throw new RuntimeException(e); + CrashReports.report(e, "Problem with load texture"); + return null; } - + } private SimpleTextures() {} diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TexturePrimitive.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TexturePrimitive.java index c59405e..e4f5fdc 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TexturePrimitive.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TexturePrimitive.java @@ -24,27 +24,28 @@ import java.util.Arrays; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class TexturePrimitive implements OpenGLDeletable { - + private static final int NOT_LOADED = -1; - + private static int[] currentlyBound = new int[32]; static { Arrays.fill(currentlyBound, NOT_LOADED); } - + private int handle = NOT_LOADED; private TextureData pixels; public TexturePrimitive(TextureData pixels) { this.pixels = pixels; } - + public TextureData getData() { return pixels; } - + public int getBufferWidth() { return pixels.getBufferWidth(); } @@ -64,21 +65,21 @@ public class TexturePrimitive implements OpenGLDeletable { public boolean isLoaded() { return handle != NOT_LOADED; } - + public void bind(int slot) { if (!isLoaded()) { load(); } - + if (currentlyBound[slot] == handle) { return; } - + int code = GL_TEXTURE0 + slot; - + glActiveTexture(code); glBindTexture(GL_TEXTURE_2D, handle); - + currentlyBound[slot] = handle; } @@ -87,9 +88,9 @@ public class TexturePrimitive implements OpenGLDeletable { handle = pixels.load(); OpenGLObjectTracker.register(this); - + if (handle < 0) { - throw new RuntimeException("oops"); + CrashReports.report(null, "Failed to create texture"); } } diff --git a/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java b/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java index 413ddab..16f7b05 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java @@ -3,6 +3,8 @@ package ru.windcorp.progressia.client.localization; import java.lang.ref.WeakReference; import java.util.*; +import ru.windcorp.progressia.common.util.crash.CrashReports; + public class Localizer { private static final Localizer INSTANCE = new Localizer("assets/languages/", "en-US"); @@ -17,7 +19,7 @@ public class Localizer { private final Collection> listeners = Collections.synchronizedCollection(new LinkedList<>()); - //lang list must be in the same folder as .lang files + // lang list must be in the same folder as .lang files public Localizer(String langFolder) { this.langFolder = langFolder; this.langList = new Parser(langFolder + "lang_list.txt").parse(); @@ -41,7 +43,7 @@ public class Localizer { data = new Parser(langFolder + this.language + ".lang").parse(); pokeListeners(language); } else { - throw new RuntimeException("Language not found: " + language); + CrashReports.report(null, "Language not found: %s", language); } } @@ -64,7 +66,7 @@ public class Localizer { } private void pokeListeners(String newLanguage) { - //TODO extract as weak bus listener class + // TODO extract as weak bus listener class synchronized (listeners) { Iterator> iterator = listeners.iterator(); while (iterator.hasNext()) { diff --git a/src/main/java/ru/windcorp/progressia/client/localization/Parser.java b/src/main/java/ru/windcorp/progressia/client/localization/Parser.java index cfa6022..c0438d5 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/Parser.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/Parser.java @@ -3,6 +3,7 @@ package ru.windcorp.progressia.client.localization; import ru.windcorp.jputil.chars.EscapeException; import ru.windcorp.jputil.chars.Escaper; import ru.windcorp.progressia.common.resource.ResourceManager; +import ru.windcorp.progressia.common.util.crash.CrashReports; import java.io.IOException; import java.io.Reader; @@ -54,7 +55,7 @@ public class Parser { if (c == '=') { String key = ESCAPER.escape(stringBuilder.toString()); stringBuilder.setLength(0); - rawData.read(); //skip a char + rawData.read(); // skip a char while (true) { code = rawData.read(); if (code == -1) { @@ -80,7 +81,8 @@ public class Parser { } } catch (IOException | EscapeException e) { - throw new RuntimeException(e); + CrashReports.report(e, "Problems with parsing"); + return null; } return parsedData; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderRegistry.java b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderRegistry.java index e79cebe..1e33fd3 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderRegistry.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderRegistry.java @@ -7,16 +7,17 @@ import ru.windcorp.progressia.client.graphics.texture.TexturePrimitive; import ru.windcorp.progressia.client.graphics.texture.TextureSettings; import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.common.util.NamespacedRegistry; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class EntityRenderRegistry extends NamespacedRegistry { - + private static final EntityRenderRegistry INSTANCE = new EntityRenderRegistry(); public static EntityRenderRegistry getInstance() { return INSTANCE; } - + public static TexturePrimitive getEntityTexture(String name) { try { return new TexturePrimitive( @@ -28,7 +29,8 @@ public class EntityRenderRegistry extends NamespacedRegistry { ).getData() ); } catch (IOException e) { - throw new RuntimeException(e); + CrashReports.report(e, "__DOC__ME__"); + return null; } } diff --git a/src/main/java/ru/windcorp/progressia/common/resource/Resource.java b/src/main/java/ru/windcorp/progressia/common/resource/Resource.java index 7a14329..d2e42ea 100644 --- a/src/main/java/ru/windcorp/progressia/common/resource/Resource.java +++ b/src/main/java/ru/windcorp/progressia/common/resource/Resource.java @@ -30,50 +30,53 @@ import com.google.common.io.CharStreams; import ru.windcorp.progressia.Progressia; import ru.windcorp.progressia.common.util.Named; +import ru.windcorp.progressia.common.util.crash.CrashReports; public class Resource extends Named { - + public Resource(String name) { super(name); } - + public InputStream getInputStream() { // TODO Do proper resource lookup return Progressia.class.getClassLoader().getResourceAsStream(getName()); } - + public Reader getReader() { return new InputStreamReader(getInputStream()); } - + public String readAsString() { try (Reader reader = getReader()) { return CharStreams.toString(reader); } catch (IOException e) { - throw new RuntimeException(e); // TODO handle gracefully + CrashReports.report(e, "__DOC__ME__"); + return null; } } - + public ByteBuffer readAsBytes(ByteBuffer output) { byte[] byteArray; try (InputStream stream = getInputStream()) { byteArray = ByteStreams.toByteArray(stream); } catch (IOException e) { - throw new RuntimeException(e); // TODO handle gracefully + CrashReports.report(e, "__DOC__ME__"); + return null; } - + if (output == null || output.remaining() < byteArray.length) { output = BufferUtils.createByteBuffer(byteArray.length); } - + int position = output.position(); output.put(byteArray); output.limit(output.position()); output.position(position); - + return output; } - + public ByteBuffer readAsBytes() { return readAsBytes(null); } diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/CrashReportGenerator.java b/src/main/java/ru/windcorp/progressia/common/util/crash/CrashReports.java similarity index 76% rename from src/main/java/ru/windcorp/progressia/common/util/crash/CrashReportGenerator.java rename to src/main/java/ru/windcorp/progressia/common/util/crash/CrashReports.java index 18bacba..ce4cdee 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/CrashReportGenerator.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/CrashReports.java @@ -1,216 +1,212 @@ -package ru.windcorp.progressia.common.util.crash; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.core.util.StringBuilderWriter; - -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; - -public class CrashReportGenerator { - - private CrashReportGenerator() {} - - private static final Path CRASH_REPORTS_PATH = Paths.get("crash-reports"); - - private static final Collection PROVIDERS = - Collections.synchronizedCollection(new ArrayList<>()); - - private static final Collection ANALYZERS = - Collections.synchronizedCollection(new ArrayList<>()); - - private static final Logger LOGGER = LogManager.getLogger("crash"); - - /** - * This method never returns. - *

- * TODO document - * @param throwable - * @param messageFormat - * @param args - */ - public static void crash(Throwable throwable, String messageFormat, Object... args) { - StringBuilder output = new StringBuilder(); - - appendContextProviders(output); - addSeparator(output); - if (appendAnalyzers(output, throwable, messageFormat, args)) { - addSeparator(output); - } - - appendMessageFormat(output, messageFormat, args); - - appendStackTrace(output, throwable); - - export(output.toString()); - - System.exit(0); - } - - private static void appendContextProviders(StringBuilder output) { - - // Do a local copy to avoid deadlocks -OLEGSHA - ContextProvider[] localProvidersCopy = - PROVIDERS.toArray(new ContextProvider[PROVIDERS.size()]); - - for (ContextProvider provider : localProvidersCopy) { - if (provider == null) continue; - - addSeparator(output); - - try { - Map buf = new HashMap<>(); - provider.provideContext(buf); - - if (!buf.isEmpty()) { - output.append("Provider name: ").append(provider.getName()).append("\n"); - for (Map.Entry entry : buf.entrySet()) { - output.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); - } - } - } catch (Throwable t) { - output.append("\n"); - - String providerName; - - try { - providerName = provider.getName(); - } catch (Throwable t1) { - providerName = provider.getClass().getName(); - } - - output.append(providerName).append(" is broken").append("\n"); - // ContextProvider is broken - } - } - } - - private static boolean appendAnalyzers( - StringBuilder output, - Throwable throwable, String messageFormat, Object[] args - ) { - boolean analyzerResponsesExist = false; - - // Do a local copy to avoid deadlocks -OLEGSHA - Analyzer[] localAnalyzersCopy = - ANALYZERS.toArray(new Analyzer[ANALYZERS.size()]); - - for (Analyzer analyzer : localAnalyzersCopy) { - if (analyzer == null) continue; - - String answer; - try { - answer = analyzer.analyze(throwable, messageFormat, args); - - if (answer != null && !answer.isEmpty()) { - analyzerResponsesExist = true; - output.append(analyzer.getName()).append(": ").append(answer).append("\n"); - } - } catch (Throwable t) { - analyzerResponsesExist = true; - - output.append("\n"); - - String analyzerName; - - try { - analyzerName = analyzer.getName(); - } catch (Throwable t1) { - analyzerName = analyzer.getClass().getName(); - } - - output.append(analyzerName).append(" is broken").append("\n"); - // Analyzer is broken - } - } - - return analyzerResponsesExist; - } - - private static void appendMessageFormat(StringBuilder output, String messageFormat, Object... arg) { - output.append("Provided description: \n").append(String.format(messageFormat, arg)).append("\n"); - - addSeparator(output); - } - - private static void appendStackTrace(StringBuilder output, Throwable throwable) { - output.append("Stacktrace: \n"); - - if (throwable == null) { - output.append("no Throwable provided").append("\n"); - return; - } - - // Formatting to a human-readable string - Writer sink = new StringBuilderWriter(output); - try { - throwable.printStackTrace(new PrintWriter(sink)); - } catch (Exception e) { - // PLAK - } - output.append("\n"); - } - - private static void export(String report) { - try { - LOGGER.fatal("/n" + report); - } catch (Exception e) { - // PLAK - } - - System.err.println(report); - - generateCrashReportFiles(report); - } - - private static void generateCrashReportFiles(String output) { - Date date = new Date(); - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss"); - - try { - if (!Files.exists(CRASH_REPORTS_PATH)) Files.createDirectory(CRASH_REPORTS_PATH); - - createFileForCrashReport(output, CRASH_REPORTS_PATH.toString() + "/latest.log"); - createFileForCrashReport(output, CRASH_REPORTS_PATH.toString() + "/crash-" + dateFormat.format(date) + ".log"); - } catch (Throwable t) { - // Crash Report not created - } - } - - private static void createFileForCrashReport(String buffer, String filename) { - try ( - BufferedWriter writer = Files.newBufferedWriter( - Paths.get(filename), - StandardCharsets.UTF_8 - ) - ) { - writer.write(buffer); - } catch (IOException ex) { - // Crash Report not created - } - } - - public static void registerProvider(ContextProvider provider) { - PROVIDERS.add(provider); - } - - public static void registerAnalyzer(Analyzer analyzer) { - ANALYZERS.add(analyzer); - } - - private static void addSeparator(StringBuilder sb) { - sb.append( - // 80 chars - "--------------------------------------------------------------------------------" - ).append("\n"); - } -} +package ru.windcorp.progressia.common.util.crash; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.util.StringBuilderWriter; + +import ru.windcorp.jputil.chars.StringUtil; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +public class CrashReports { + + private CrashReports() { + } + + private static final Path CRASH_REPORTS_PATH = Paths.get("crash-reports"); + + private static final Collection PROVIDERS = Collections.synchronizedCollection(new ArrayList<>()); + + private static final Collection ANALYZERS = Collections.synchronizedCollection(new ArrayList<>()); + + private static final Logger LOGGER = LogManager.getLogger("crash"); + + /** + * This method never returns. + *

+ * TODO document + * + * @param throwable + * @param messageFormat + * @param args + */ + public static void report(Throwable throwable, String messageFormat, Object... args) { + StringBuilder output = new StringBuilder(); + + appendContextProviders(output); + addSeparator(output); + if (appendAnalyzers(output, throwable, messageFormat, args)) { + addSeparator(output); + } + + appendMessageFormat(output, messageFormat, args); + + appendStackTrace(output, throwable); + + export(output.toString()); + + System.exit(0); + } + + private static void appendContextProviders(StringBuilder output) { + + // Do a local copy to avoid deadlocks -OLEGSHA + ContextProvider[] localProvidersCopy = PROVIDERS.toArray(new ContextProvider[PROVIDERS.size()]); + + for (ContextProvider provider : localProvidersCopy) { + if (provider == null) + continue; + + addSeparator(output); + + try { + Map buf = new HashMap<>(); + provider.provideContext(buf); + + if (!buf.isEmpty()) { + output.append("Provider name: ").append(provider.getName()).append("\n"); + for (Map.Entry entry : buf.entrySet()) { + output.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); + } + } + } catch (Throwable t) { + output.append("\n"); + + String providerName; + + try { + providerName = provider.getName(); + } catch (Throwable t1) { + providerName = provider.getClass().getName(); + } + + output.append(providerName).append(" is broken").append("\n"); + // ContextProvider is broken + } + } + } + + private static boolean appendAnalyzers(StringBuilder output, Throwable throwable, String messageFormat, + Object[] args) { + boolean analyzerResponsesExist = false; + + // Do a local copy to avoid deadlocks -OLEGSHA + Analyzer[] localAnalyzersCopy = ANALYZERS.toArray(new Analyzer[ANALYZERS.size()]); + + for (Analyzer analyzer : localAnalyzersCopy) { + if (analyzer == null) + continue; + + String answer; + try { + answer = analyzer.analyze(throwable, messageFormat, args); + + if (answer != null && !answer.isEmpty()) { + analyzerResponsesExist = true; + output.append(analyzer.getName()).append(": ").append(answer).append("\n"); + } + } catch (Throwable t) { + analyzerResponsesExist = true; + + output.append("\n"); + + String analyzerName; + + try { + analyzerName = analyzer.getName(); + } catch (Throwable t1) { + analyzerName = analyzer.getClass().getName(); + } + + output.append(analyzerName).append(" is broken").append("\n"); + // Analyzer is broken + } + } + + return analyzerResponsesExist; + } + + private static void appendMessageFormat(StringBuilder output, String messageFormat, Object... arg) { + output.append("Provided description: \n").append(String.format(messageFormat, arg)).append("\n"); + + addSeparator(output); + } + + private static void appendStackTrace(StringBuilder output, Throwable throwable) { + output.append("Stacktrace: \n"); + + if (throwable == null) { + output.append("no Throwable provided").append("\n"); + return; + } + + // Formatting to a human-readable string + Writer sink = new StringBuilderWriter(output); + try { + throwable.printStackTrace(new PrintWriter(sink)); + } catch (Exception e) { + // PLAK + } + output.append("\n"); + } + + private static void export(String report) { + try { + LOGGER.fatal("/n" + report); + } catch (Exception e) { + // PLAK + } + + System.err.println(report); + + generateCrashReportFiles(report); + } + + private static void generateCrashReportFiles(String output) { + Date date = new Date(); + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss"); + + try { + if (!Files.exists(CRASH_REPORTS_PATH)) + Files.createDirectory(CRASH_REPORTS_PATH); + + createFileForCrashReport(output, CRASH_REPORTS_PATH.toString() + "/latest.log"); + createFileForCrashReport(output, + CRASH_REPORTS_PATH.toString() + "/crash-" + dateFormat.format(date) + ".log"); + } catch (Throwable t) { + // Crash Report not created + } + } + + private static void createFileForCrashReport(String buffer, String filename) { + try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(filename), StandardCharsets.UTF_8)) { + writer.write(buffer); + } catch (IOException ex) { + // Crash Report not created + } + } + + public static void registerProvider(ContextProvider provider) { + PROVIDERS.add(provider); + } + + public static void registerAnalyzer(Analyzer analyzer) { + ANALYZERS.add(analyzer); + } + + private static void addSeparator(StringBuilder sb) { + sb.append( + // 80 chars + "--------------------------------------------------------------------------------").append("\n"); + } +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketEntityChange.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketEntityChange.java index f6c5c8b..1b6d5bb 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketEntityChange.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketEntityChange.java @@ -7,25 +7,26 @@ import java.io.IOException; import ru.windcorp.progressia.common.comms.packets.PacketWorldChange; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.DataBuffer; +import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.WorldData; public class PacketEntityChange extends PacketWorldChange { - + private long entityId; private final DataBuffer buffer = new DataBuffer(); public PacketEntityChange() { super("Core", "EntityChange"); } - + public long getEntityId() { return entityId; } - + public void setEntityId(long entityId) { this.entityId = entityId; } - + public DataBuffer getBuffer() { return buffer; } @@ -41,19 +42,15 @@ public class PacketEntityChange extends PacketWorldChange { @Override public void apply(WorldData world) { EntityData entity = world.getEntity(getEntityId()); - + if (entity == null) { - throw new RuntimeException( - "Entity with ID " + getEntityId() + " not found" - ); + CrashReports.report(null, "Entity with ID %d not found", getEntityId()); } - + try { entity.read(getReader(), IOContext.COMMS); } catch (IOException e) { - throw new RuntimeException( - "Entity could not be read", e - ); + CrashReports.report(e, "Entity could not be read"); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/ImplementedChangeTracker.java b/src/main/java/ru/windcorp/progressia/server/world/ImplementedChangeTracker.java index 70fada1..960f77d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ImplementedChangeTracker.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ImplementedChangeTracker.java @@ -11,6 +11,7 @@ import ru.windcorp.progressia.common.comms.packets.PacketWorldChange; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.LowOverheadCache; import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; @@ -21,50 +22,50 @@ import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.Server; public class ImplementedChangeTracker implements Changer { - + public static interface ChangeImplementation { void applyOnServer(WorldData world); Packet asPacket(); } - + private static class SetBlock extends PacketWorldChange implements ChangeImplementation { private final Vec3i position = new Vec3i(); private BlockData block; - + public SetBlock() { super("Core", "SetBlock"); } - + public void initialize(Vec3i position, BlockData block) { this.position.set(position.x, position.y, position.z); this.block = block; } - + @Override public void applyOnServer(WorldData world) { Vec3i blockInChunk = Vectors.grab3i(); Coordinates.convertInWorldToInChunk(position, blockInChunk); - + world.getChunkByBlock(position).setBlock(blockInChunk, block); - + Vectors.release(blockInChunk); } - + @Override public void apply(WorldData world) { applyOnServer(world); } - + @Override public Packet asPacket() { return this; } - + } - + private static class AddOrRemoveTile extends PacketWorldChange implements ChangeImplementation { @@ -72,13 +73,13 @@ public class ImplementedChangeTracker implements Changer { private final Vec3i position = new Vec3i(); private BlockFace face; private TileData tile; - + private boolean shouldAdd; - + public AddOrRemoveTile() { super("Core", "AddOrRemoveTile"); } - + public void initialize( Vec3i position, BlockFace face, TileData tile, @@ -89,52 +90,51 @@ public class ImplementedChangeTracker implements Changer { this.tile = tile; this.shouldAdd = shouldAdd; } - + @Override public void applyOnServer(WorldData world) { Vec3i blockInChunk = Vectors.grab3i(); Coordinates.convertInWorldToInChunk(position, blockInChunk); - - List tiles = world.getChunkByBlock(position) - .getTiles(blockInChunk, face); - + + List tiles = world.getChunkByBlock(position).getTiles(blockInChunk, face); + if (shouldAdd) { tiles.add(tile); } else { tiles.remove(tile); } - + Vectors.release(blockInChunk); } - + @Override public void apply(WorldData world) { applyOnServer(world); } - + @Override public Packet asPacket() { return this; } - + } - + private static class ChangeEntity implements ChangeImplementation { - + private EntityData entity; private Change change; - + private final PacketEntityChange packet = new PacketEntityChange(); public void set(T entity, Change change) { this.entity = entity; this.change = change; - + packet.setEntityId(entity.getEntityId()); try { entity.write(packet.getWriter(), IOContext.COMMS); } catch (IOException e) { - throw new RuntimeException(e); + CrashReports.report(e, "__DOC__ME__"); } } @@ -142,11 +142,11 @@ public class ImplementedChangeTracker implements Changer { @Override public void applyOnServer(WorldData world) { ((Change) change).change(entity); - + try { entity.write(packet.getWriter(), IOContext.COMMS); } catch (IOException e) { - throw new RuntimeException("Entity could not be written", e); + CrashReports.report(e, "Entity could not be written"); } } @@ -154,11 +154,11 @@ public class ImplementedChangeTracker implements Changer { public Packet asPacket() { return packet; } - + } private final List changes = new ArrayList<>(1024); - + private final LowOverheadCache setBlockCache = new LowOverheadCache<>(SetBlock::new); @@ -174,21 +174,21 @@ public class ImplementedChangeTracker implements Changer { change.initialize(pos, block); changes.add(change); } - + @Override public void addTile(Vec3i block, BlockFace face, TileData tile) { AddOrRemoveTile change = addOrRemoveTileCache.grab(); change.initialize(block, face, tile, true); changes.add(change); } - + @Override public void removeTile(Vec3i block, BlockFace face, TileData tile) { AddOrRemoveTile change = addOrRemoveTileCache.grab(); change.initialize(block, face, tile, false); changes.add(change); } - + @Override public void changeEntity( T entity, Change change @@ -197,7 +197,7 @@ public class ImplementedChangeTracker implements Changer { changeRecord.set(entity, change); changes.add(changeRecord); } - + public void applyChanges(Server server) { changes.forEach(c -> c.applyOnServer(server.getWorld().getData())); changes.stream().map(ChangeImplementation::asPacket).filter(Objects::nonNull).forEach( @@ -206,7 +206,7 @@ public class ImplementedChangeTracker implements Changer { changes.forEach(this::release); changes.clear(); } - + private void release(ChangeImplementation c) { if (c instanceof SetBlock) { setBlockCache.release((SetBlock) c);