Introduced crash reports

This commit is contained in:
Sergey Karmanov 2020-11-14 20:38:49 +03:00
parent a425af01d8
commit c1194b7601
21 changed files with 789 additions and 818 deletions

View File

@ -502,7 +502,8 @@ public class ArrayUtil {
int end = offset + length; int end = offset + length;
if (end > arrayLength || offset < 0) 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; return length;
} }
@ -517,7 +518,8 @@ public class ArrayUtil {
throw new IllegalArgumentException("Start > end: " + start + " > " + end); throw new IllegalArgumentException("Start > end: " + start + " > " + end);
if (end > arrayLength || start < 0) 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; return end;
} }

View File

@ -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.texture.Atlases;
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
import ru.windcorp.progressia.common.resource.ResourceManager; 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.server.ServerState;
import ru.windcorp.progressia.test.TestContent; import ru.windcorp.progressia.test.TestContent;
@ -39,8 +40,7 @@ public class ClientProxy implements Proxy {
RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init); RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init);
RenderTaskQueue.waitAndInvoke(() -> Typefaces.setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz")))); RenderTaskQueue.waitAndInvoke(() -> Typefaces.setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz"))));
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block CrashReports.report(e, "ClientProxy failed");
e.printStackTrace();
} }
TestContent.registerContent(); TestContent.registerContent();

View File

@ -20,7 +20,7 @@ package ru.windcorp.progressia.client;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import ru.windcorp.progressia.ProgressiaLauncher; 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.analyzers.OutOfMemoryAnalyzer;
import ru.windcorp.progressia.common.util.crash.providers.OSContextProvider; import ru.windcorp.progressia.common.util.crash.providers.OSContextProvider;
@ -31,14 +31,13 @@ public class ProgressiaClientMain {
public static void main(String[] args) { public static void main(String[] args) {
logger.info("App started!"); logger.info("App started!");
CrashReportGenerator.registerProvider(new OSContextProvider()); CrashReports.registerProvider(new OSContextProvider());
CrashReportGenerator.registerAnalyzer(new OutOfMemoryAnalyzer()); CrashReports.registerAnalyzer(new OutOfMemoryAnalyzer());
try { try {
@SuppressWarnings("unused") @SuppressWarnings("unused")
long[] ssdss = new long[1 << 30]; long[] ssdss = new long[1 << 30];
} catch (Throwable t) } catch (Throwable t) {
{ CrashReports.report(t, "u %s stupid", "vry");
CrashReportGenerator.crash(t, "u %s stupid", "vry");
} }
ProgressiaLauncher.launch(args, new ClientProxy()); ProgressiaLauncher.launch(args, new ClientProxy());

View File

@ -8,6 +8,7 @@ import ru.windcorp.progressia.common.comms.CommsListener;
import ru.windcorp.progressia.common.comms.packets.Packet; import ru.windcorp.progressia.common.comms.packets.Packet;
import ru.windcorp.progressia.common.comms.packets.PacketSetLocalPlayer; import ru.windcorp.progressia.common.comms.packets.PacketSetLocalPlayer;
import ru.windcorp.progressia.common.comms.packets.PacketWorldChange; 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.EntityData;
import ru.windcorp.progressia.common.world.entity.PacketEntityChange; import ru.windcorp.progressia.common.world.entity.PacketEntityChange;
@ -41,7 +42,7 @@ public class DefaultClientCommsListener implements CommsListener {
); );
if (entity == null) { if (entity == null) {
throw new RuntimeException(""); CrashReports.report(null, "Player entity not found");
} }
getClient().setLocalPlayer(entity); getClient().setLocalPlayer(entity);

View File

@ -24,6 +24,7 @@ import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable; 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.attributes.Attribute;
import ru.windcorp.progressia.client.graphics.backend.shaders.uniforms.Uniform; import ru.windcorp.progressia.client.graphics.backend.shaders.uniforms.Uniform;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Program implements OpenGLDeletable { public class Program implements OpenGLDeletable {
@ -39,7 +40,7 @@ public class Program implements OpenGLDeletable {
glLinkProgram(handle); glLinkProgram(handle);
if (glGetProgrami(handle, GL_LINK_STATUS) == GL_FALSE) { 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));
} }
} }

View File

@ -26,12 +26,12 @@ import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
import ru.windcorp.progressia.common.resource.Resource; import ru.windcorp.progressia.common.resource.Resource;
import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Shader implements OpenGLDeletable { public class Shader implements OpenGLDeletable {
public static enum ShaderType { public static enum ShaderType {
VERTEX(GL_VERTEX_SHADER), VERTEX(GL_VERTEX_SHADER), FRAGMENT(GL_FRAGMENT_SHADER);
FRAGMENT(GL_FRAGMENT_SHADER);
private final int glCode; private final int glCode;
@ -79,7 +79,7 @@ public class Shader implements OpenGLDeletable {
if (glGetShaderi(handle, GL_COMPILE_STATUS) == GL_FALSE) { if (glGetShaderi(handle, GL_COMPILE_STATUS) == GL_FALSE) {
System.out.println("***************** ERROR ******************"); System.out.println("***************** ERROR ******************");
System.out.println(source); System.out.println(source);
throw new RuntimeException("Bad shader:\n" + glGetShaderInfoLog(handle)); CrashReports.report(null, "Bad shader:\n %s", glGetShaderInfoLog(handle));
} }
} }

View File

@ -18,6 +18,7 @@
package ru.windcorp.progressia.client.graphics.backend.shaders.attributes; package ru.windcorp.progressia.client.graphics.backend.shaders.attributes;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program; import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Attribute { public class Attribute {
@ -26,7 +27,7 @@ public class Attribute {
public Attribute(int handle, Program program) { public Attribute(int handle, Program program) {
if (handle < 0) { if (handle < 0) {
throw new RuntimeException("Bad handle: " + handle); CrashReports.report(null, "Bad handle: %s", handle);
} }
this.handle = handle; this.handle = handle;

View File

@ -18,6 +18,7 @@
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program; import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Uniform { public class Uniform {
@ -26,7 +27,7 @@ public class Uniform {
public Uniform(int handle, Program program) { public Uniform(int handle, Program program) {
if (handle < 0) { if (handle < 0) {
throw new RuntimeException("Bad handle: " + handle); CrashReports.report(null, "Bad handle: %s", handle);
} }
this.handle = handle; this.handle = handle;

View File

@ -21,14 +21,13 @@ import ru.windcorp.progressia.client.graphics.texture.Texture;
import ru.windcorp.progressia.client.graphics.texture.TextureDataEditor; import ru.windcorp.progressia.client.graphics.texture.TextureDataEditor;
import ru.windcorp.progressia.client.graphics.texture.TextureSettings; import ru.windcorp.progressia.client.graphics.texture.TextureSettings;
import ru.windcorp.progressia.common.resource.Resource; import ru.windcorp.progressia.common.resource.Resource;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class GNUUnifontLoader { public class GNUUnifontLoader {
private static final AtlasGroup ATLAS_GROUP_GNU_UNIFONT = private static final AtlasGroup ATLAS_GROUP_GNU_UNIFONT = new AtlasGroup("GNUUnifont", 1 << 12);
new AtlasGroup("GNUUnifont", 1 << 12);
private static final TextureSettings TEXTURE_SETTINGS = private static final TextureSettings TEXTURE_SETTINGS = new TextureSettings(false);
new TextureSettings(false);
private static final int BITS_PER_HEX_DIGIT = 4; private static final int BITS_PER_HEX_DIGIT = 4;
private static final int PREFIX_LENGTH = "0000:".length(); private static final int PREFIX_LENGTH = "0000:".length();
@ -55,29 +54,17 @@ public class GNUUnifontLoader {
public static GNUUnifont load(Resource resource) { public static GNUUnifont load(Resource resource) {
try (BufferedReader reader = createReader(resource)) { try (BufferedReader reader = createReader(resource)) {
return createStream(reader) return createStream(reader).map(GNUUnifontLoader::parse).map(GNUUnifontLoader::addToAtlas)
.map(GNUUnifontLoader::parse) .collect(Collectors.collectingAndThen(createMapper(), GNUUnifont::new));
.map(GNUUnifontLoader::addToAtlas)
.collect(Collectors.collectingAndThen(
createMapper(),
GNUUnifont::new
));
} catch (IOException | UncheckedIOException e) { } catch (IOException | UncheckedIOException e) {
throw new RuntimeException(e); CrashReports.report(e, "Problem with load GNUUnifont");
return null;
} }
} }
private static BufferedReader createReader(Resource resource) private static BufferedReader createReader(Resource resource) throws IOException {
throws IOException
{
return new BufferedReader( return new BufferedReader(
new InputStreamReader( new InputStreamReader(new GZIPInputStream(resource.getInputStream()), StandardCharsets.UTF_8));
new GZIPInputStream(
resource.getInputStream()
),
StandardCharsets.UTF_8
)
);
} }
private static Stream<String> createStream(BufferedReader reader) { private static Stream<String> createStream(BufferedReader reader) {
@ -90,20 +77,14 @@ public class GNUUnifontLoader {
char c = getChar(declar); char c = getChar(declar);
TextureDataEditor editor = new TextureDataEditor( TextureDataEditor editor = new TextureDataEditor(width, GNUUnifont.HEIGHT, width, GNUUnifont.HEIGHT,
width, GNUUnifont.HEIGHT, TEXTURE_SETTINGS);
width, GNUUnifont.HEIGHT,
TEXTURE_SETTINGS
);
for (int y = 0; y < GNUUnifont.HEIGHT; ++y) { for (int y = 0; y < GNUUnifont.HEIGHT; ++y) {
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
int bit = x + y * width; int bit = x + y * width;
editor.setPixel( editor.setPixel(x, GNUUnifont.HEIGHT - y - 1, getBit(declar, bit) ? 0xFFFFFFFF : 0x00000000);
x, GNUUnifont.HEIGHT - y - 1,
getBit(declar, bit) ? 0xFFFFFFFF : 0x00000000
);
} }
} }
@ -114,9 +95,7 @@ public class GNUUnifontLoader {
int result = 0; int result = 0;
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
result = result = (result << BITS_PER_HEX_DIGIT) | getHexValue(declar.charAt(i));
(result << BITS_PER_HEX_DIGIT) |
getHexValue(declar.charAt(i));
} }
return (char) result; return (char) result;
@ -140,33 +119,38 @@ public class GNUUnifontLoader {
private static void checkDeclaration(String declar, int width) { private static void checkDeclaration(String declar, int width) {
if (!GNUUnifont.WIDTHS.contains(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) { 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) { for (int i = 0; i < declar.length(); ++i) {
if (i == BITS_PER_HEX_DIGIT) { if (i == BITS_PER_HEX_DIGIT) {
if (declar.charAt(i) != ':') { 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 { } else {
char c = declar.charAt(i); char c = declar.charAt(i);
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))) { 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) { private static int getHexValue(char digit) {
if (digit < '0') throw new NumberFormatException(digit + " is not a hex digit (0-9A-F expected)"); if (digit < '0')
if (digit <= '9') return digit - '0'; throw new NumberFormatException(digit + " is not a hex digit (0-9A-F expected)");
if (digit < 'A') throw new NumberFormatException(digit + " is not a hex digit (0-9A-F expected)"); if (digit <= '9')
if (digit <= 'F') return digit - 'A' + 0xA; 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)"); throw new NumberFormatException(digit + " is not a hex digit (0-9A-F expected)");
} }
@ -175,11 +159,8 @@ public class GNUUnifontLoader {
return new AtlasGlyph(glyph.c, new SimpleTexture(sprite)); return new AtlasGlyph(glyph.c, new SimpleTexture(sprite));
} }
private static private static Collector<AtlasGlyph, ?, TCharObjectMap<Texture>> createMapper() {
Collector<AtlasGlyph, ?, TCharObjectMap<Texture>> return Collector.of(TCharObjectHashMap<Texture>::new,
createMapper() {
return Collector.of(
TCharObjectHashMap<Texture>::new,
(map, glyph) -> map.put(glyph.c, glyph.texture), (map, glyph) -> map.put(glyph.c, glyph.texture),
@ -188,10 +169,10 @@ public class GNUUnifontLoader {
return a; return a;
}, },
Characteristics.UNORDERED Characteristics.UNORDERED);
);
} }
private GNUUnifontLoader() {} private GNUUnifontLoader() {
}
} }

View File

@ -39,11 +39,11 @@ 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.InputBus;
import ru.windcorp.progressia.client.graphics.input.bus.InputListener; import ru.windcorp.progressia.client.graphics.input.bus.InputListener;
import ru.windcorp.progressia.common.util.Named; import ru.windcorp.progressia.common.util.Named;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Component extends Named { public class Component extends Named {
private final List<Component> children = private final List<Component> children = Collections.synchronizedList(new CopyOnWriteArrayList<>());
Collections.synchronizedList(new CopyOnWriteArrayList<>());
private Component parent = null; private Component parent = null;
@ -88,7 +88,8 @@ public class Component extends Named {
public Component getChild(int index) { public Component getChild(int index) {
synchronized (getChildren()) { synchronized (getChildren()) {
if (index < 0 || index >= getChildren().size()) return null; if (index < 0 || index >= getChildren().size())
return null;
return getChildren().get(index); return getChildren().get(index);
} }
} }
@ -107,7 +108,8 @@ public class Component extends Named {
} }
public void moveChild(Component child, int newIndex) { 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)) { if (getChildren().remove(child)) {
getChildren().add(newIndex, child); getChildren().add(newIndex, child);
@ -123,7 +125,8 @@ public class Component extends Named {
} }
public Component addChild(Component child, int index) { public Component addChild(Component child, int index) {
if (index == -1) index = getChildren().size(); if (index == -1)
index = getChildren().size();
invalidate(); invalidate();
getChildren().add(index, child); getChildren().add(index, child);
@ -232,7 +235,7 @@ public class Component extends Named {
valid = true; valid = true;
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); CrashReports.report(e, "__DOC__ME__");
} }
} }
@ -245,7 +248,7 @@ public class Component extends Named {
try { try {
return getLayout().calculatePreferredSize(this); return getLayout().calculatePreferredSize(this);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); CrashReports.report(e, "__DOC__ME__");
} }
} }
@ -342,11 +345,12 @@ public class Component extends Named {
} }
private Component getNextFocusCandidate(boolean canUseChildren) { private Component getNextFocusCandidate(boolean canUseChildren) {
if (canUseChildren) synchronized (getChildren()) { if (canUseChildren)
if (!getChildren().isEmpty()) { synchronized (getChildren()) {
return getChild(0); if (!getChildren().isEmpty()) {
return getChild(0);
}
} }
}
Component parent = getParent(); Component parent = getParent();
if (parent != null) { if (parent != null) {
@ -458,20 +462,19 @@ public class Component extends Named {
} }
public void removeListener(Object listener) { public void removeListener(Object listener) {
if (eventBus == null) return; if (eventBus == null)
return;
eventBus.unregister(listener); eventBus.unregister(listener);
} }
public void dispatchEvent(Object event) { public void dispatchEvent(Object event) {
if (eventBus == null) return; if (eventBus == null)
return;
eventBus.post(event); eventBus.post(event);
} }
public <T extends InputEvent> void addListener( public <T extends InputEvent> void addListener(Class<? extends T> type, boolean handlesConsumed,
Class<? extends T> type, InputListener<T> listener) {
boolean handlesConsumed,
InputListener<T> listener
) {
if (inputBus == null) { if (inputBus == null) {
inputBus = new InputBus(); inputBus = new InputBus();
} }
@ -479,10 +482,7 @@ public class Component extends Named {
inputBus.register(type, handlesConsumed, listener); inputBus.register(type, handlesConsumed, listener);
} }
public <T extends InputEvent> void addListener( public <T extends InputEvent> void addListener(Class<? extends T> type, InputListener<T> listener) {
Class<? extends T> type,
InputListener<T> listener
) {
if (inputBus == null) { if (inputBus == null) {
inputBus = new InputBus(); inputBus = new InputBus();
} }
@ -505,27 +505,29 @@ public class Component extends Named {
public void dispatchInput(Input input) { public void dispatchInput(Input input) {
try { try {
switch (input.getTarget()) { switch (input.getTarget()) {
case FOCUSED: case FOCUSED:
dispatchInputToFocused(input); dispatchInputToFocused(input);
break; break;
case HOVERED: case HOVERED:
dispatchInputToHovered(input); dispatchInputToHovered(input);
break; break;
case ALL: case ALL:
default: default:
dispatchInputToAll(input); dispatchInputToAll(input);
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); CrashReports.report(e, "__DOC__ME__");
} }
} }
private void dispatchInputToFocused(Input input) { private void dispatchInputToFocused(Input input) {
Component c = findFocused(); Component c = findFocused();
if (c == null) return; if (c == null)
if (attemptFocusTransfer(input, c)) return; return;
if (attemptFocusTransfer(input, c))
return;
while (c != null) { while (c != null) {
c.handleInput(input); c.handleInput(input);
@ -555,8 +557,10 @@ public class Component extends Named {
} }
private boolean attemptFocusTransfer(Input input, Component focused) { private boolean attemptFocusTransfer(Input input, Component focused) {
if (input.isConsumed()) return false; if (input.isConsumed())
if (!(input.getEvent() instanceof KeyEvent)) return false; return false;
if (!(input.getEvent() instanceof KeyEvent))
return false;
KeyEvent keyInput = (KeyEvent) input.getEvent(); KeyEvent keyInput = (KeyEvent) input.getEvent();
@ -574,16 +578,11 @@ public class Component extends Named {
} }
public synchronized boolean contains(int x, int y) { public synchronized boolean contains(int x, int y) {
return return x >= getX() && x < getX() + getWidth() && y >= getY() && y < getY() + getHeight();
x >= getX() && x < getX() + getWidth() &&
y >= getY() && y < getY() + getHeight();
} }
public boolean containsCursor() { public boolean containsCursor() {
return contains( return contains((int) InputTracker.getCursorX(), (int) InputTracker.getCursorY());
(int) InputTracker.getCursorX(),
(int) InputTracker.getCursorY()
);
} }
public void requestReassembly() { public void requestReassembly() {
@ -610,7 +609,7 @@ public class Component extends Named {
try { try {
assembleSelf(target); assembleSelf(target);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); CrashReports.report(e, "__DOC__ME__");
} }
assembleChildren(target); assembleChildren(target);
@ -618,7 +617,7 @@ public class Component extends Named {
try { try {
postAssembleSelf(target); postAssembleSelf(target);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); CrashReports.report(e, "__DOC__ME__");
} }
} }
@ -634,28 +633,28 @@ public class Component extends Named {
getChildren().forEach(child -> child.assemble(target)); getChildren().forEach(child -> child.assemble(target));
} }
// /** // /**
// * Returns a component that displays this component in its center. // * Returns a component that displays this component in its center.
// * @return a {@link Aligner} initialized to center this component // * @return a {@link Aligner} initialized to center this component
// */ // */
// public Component center() { // public Component center() {
// return new Aligner(this); // return new Aligner(this);
// } // }
// //
// /** // /**
// * Returns a component that aligns this component. // * Returns a component that aligns this component.
// * @return a {@link Aligner} initialized with this component // * @return a {@link Aligner} initialized with this component
// */ // */
// public Component align(double x, double y) { // public Component align(double x, double y) {
// return new Aligner(this, x, y); // return new Aligner(this, x, y);
// } // }
// //
// /** // /**
// * Returns a component that allows scrolling this component // * Returns a component that allows scrolling this component
// * @return a {@link Scroller} initialized with this component // * @return a {@link Scroller} initialized with this component
// */ // */
// public Component scroller() { // public Component scroller() {
// return new Scroller(this); // return new Scroller(this);
// } // }
} }

View File

@ -31,28 +31,25 @@ import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.map.hash.TObjectIntHashMap; import gnu.trove.map.hash.TObjectIntHashMap;
import gnu.trove.set.TIntSet; import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet; import gnu.trove.set.hash.TIntHashSet;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Keys { public class Keys {
private static final TIntObjectMap<String> CODES_TO_NAMES = private static final TIntObjectMap<String> CODES_TO_NAMES = new TIntObjectHashMap<>();
new TIntObjectHashMap<>();
private static final TObjectIntMap<String> NAMES_TO_CODES = private static final TObjectIntMap<String> NAMES_TO_CODES = new TObjectIntHashMap<>();
new TObjectIntHashMap<>();
private static final TIntSet MOUSE_BUTTONS = new TIntHashSet(); private static final TIntSet MOUSE_BUTTONS = new TIntHashSet();
private static final String KEY_PREFIX = "GLFW_KEY_"; private static final String KEY_PREFIX = "GLFW_KEY_";
private static final String MOUSE_BUTTON_PREFIX = "GLFW_MOUSE_BUTTON_"; private static final String MOUSE_BUTTON_PREFIX = "GLFW_MOUSE_BUTTON_";
private static final Set<String> IGNORE_FIELDS = private static final Set<String> IGNORE_FIELDS = new HashSet<>(
new HashSet<>(Arrays.asList( Arrays.asList("GLFW_KEY_UNKNOWN", "GLFW_KEY_LAST", "GLFW_MOUSE_BUTTON_LAST", "GLFW_MOUSE_BUTTON_1", // Alias
"GLFW_KEY_UNKNOWN", // for
"GLFW_KEY_LAST", // LEFT
"GLFW_MOUSE_BUTTON_LAST",
"GLFW_MOUSE_BUTTON_1", // Alias for LEFT
"GLFW_MOUSE_BUTTON_2", // Alias for RIGHT "GLFW_MOUSE_BUTTON_2", // Alias for RIGHT
"GLFW_MOUSE_BUTTON_3" // Alias for MIDDLE "GLFW_MOUSE_BUTTON_3" // Alias for MIDDLE
)); ));
static { static {
@ -63,28 +60,28 @@ public class Keys {
try { try {
for (Field field : GLFW.class.getFields()) { for (Field field : GLFW.class.getFields()) {
if (!Modifier.isStatic(field.getModifiers())) continue; if (!Modifier.isStatic(field.getModifiers()))
if (!Modifier.isFinal(field.getModifiers())) continue; continue;
if (!Modifier.isFinal(field.getModifiers()))
continue;
String name = field.getName(); String name = field.getName();
if ( if (!name.startsWith(KEY_PREFIX) && !name.startsWith(MOUSE_BUTTON_PREFIX))
!name.startsWith(KEY_PREFIX) && continue;
!name.startsWith(MOUSE_BUTTON_PREFIX)
) continue;
if (IGNORE_FIELDS.contains(name)) continue; if (IGNORE_FIELDS.contains(name))
continue;
addToDictionary(field); addToDictionary(field);
} }
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new RuntimeException(e); CrashReports.report(e, "Cannot access GLFW constants");
} }
} }
private static void addToDictionary(Field field) private static void addToDictionary(Field field) throws IllegalAccessException {
throws IllegalAccessException {
int value = field.getInt(null); int value = field.getInt(null);
String name = field.getName(); String name = field.getName();
@ -97,11 +94,8 @@ public class Keys {
} }
if (CODES_TO_NAMES.containsKey(value)) { if (CODES_TO_NAMES.containsKey(value)) {
throw new RuntimeException( CrashReports.report(null, "Duplicate keys: %s and %s both map to %d(0x%s)",
"Duplicate keys: " + CODES_TO_NAMES.get(value) + CODES_TO_NAMES.get(value), name, value, Integer.toHexString(value));
" and " + name + " both map to " + value +
"(0x" + Integer.toHexString(value) + ")"
);
} }
CODES_TO_NAMES.put(value, name); CODES_TO_NAMES.put(value, name);
@ -125,8 +119,7 @@ public class Keys {
name = "KEYPAD_" + name.substring("KP_".length()); name = "KEYPAD_" + name.substring("KP_".length());
} }
name = Character.toTitleCase(name.charAt(0)) + name = Character.toTitleCase(name.charAt(0)) + name.substring(1).toLowerCase();
name.substring(1).toLowerCase();
name = name.replace('_', ' '); name = name.replace('_', ' ');

View File

@ -13,6 +13,7 @@ import ru.windcorp.progressia.client.graphics.backend.RenderTaskQueue;
import ru.windcorp.progressia.common.resource.Resource; import ru.windcorp.progressia.common.resource.Resource;
import ru.windcorp.progressia.common.util.BinUtil; import ru.windcorp.progressia.common.util.BinUtil;
import ru.windcorp.progressia.common.util.Named; import ru.windcorp.progressia.common.util.Named;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Atlases { public class Atlases {
@ -24,10 +25,7 @@ public class Atlases {
this.atlasSize = atlasSize; this.atlasSize = atlasSize;
if (!BinUtil.isPowerOf2(atlasSize)) { if (!BinUtil.isPowerOf2(atlasSize)) {
throw new IllegalArgumentException( throw new IllegalArgumentException("Atlas size " + atlasSize + " is not a power of 2");
"Atlas size " + atlasSize
+ " is not a power of 2"
);
} }
} }
@ -71,11 +69,8 @@ public class Atlases {
editor.draw(data, nextX, nextY); editor.draw(data, nextX, nextY);
Sprite result = new Sprite( Sprite result = new Sprite(getPrimitive(), toPrimitiveCoords(nextX, nextY),
getPrimitive(), toPrimitiveCoords(width, height));
toPrimitiveCoords(nextX, nextY),
toPrimitiveCoords(width, height)
);
nextX += width; nextX += width;
@ -87,7 +82,7 @@ public class Atlases {
// Wrapping // Wrapping
nextY += rowHeight; // Move to next row nextY += rowHeight; // Move to next row
rowHeight = height; // Next row is at least 'height' high rowHeight = height; // Next row is at least 'height' high
nextX = 0; // Start the row over nextX = 0; // Start the row over
} else { } else {
// Not wrapping // Not wrapping
@ -99,10 +94,7 @@ public class Atlases {
} }
private Vec2 toPrimitiveCoords(int x, int y) { private Vec2 toPrimitiveCoords(int x, int y) {
return new Vec2( return new Vec2(toPrimitiveCoord(x), toPrimitiveCoord(y));
toPrimitiveCoord(x),
toPrimitiveCoord(y)
);
} }
private float toPrimitiveCoord(int c) { private float toPrimitiveCoord(int c) {
@ -152,10 +144,8 @@ public class Atlases {
private static final TextureSettings SETTINGS = new TextureSettings(false); private static final TextureSettings SETTINGS = new TextureSettings(false);
private static final Map<Resource, Sprite> LOADED = private static final Map<Resource, Sprite> LOADED = new HashMap<>();
new HashMap<>(); private static final Multimap<AtlasGroup, Atlas> ATLASES = MultimapBuilder.hashKeys().arrayListValues().build();
private static final Multimap<AtlasGroup, Atlas> ATLASES =
MultimapBuilder.hashKeys().arrayListValues().build();
public static Sprite getSprite(Resource resource, AtlasGroup group) { public static Sprite getSprite(Resource resource, AtlasGroup group) {
return LOADED.computeIfAbsent(resource, k -> loadSprite(k, group)); return LOADED.computeIfAbsent(resource, k -> loadSprite(k, group));
@ -163,12 +153,12 @@ public class Atlases {
private static Sprite loadSprite(Resource resource, AtlasGroup group) { private static Sprite loadSprite(Resource resource, AtlasGroup group) {
try { try {
TextureDataEditor data = TextureDataEditor data = TextureLoader.loadPixels(resource, SETTINGS);
TextureLoader.loadPixels(resource, SETTINGS);
return loadSprite(data.getData(), group); return loadSprite(data.getData(), group);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); CrashReports.report(e, "Problem with load atlases sprite");
return null;
} }
} }
@ -180,14 +170,11 @@ public class Atlases {
private static Atlas getReadyAtlas(AtlasGroup group, TextureData data) { private static Atlas getReadyAtlas(AtlasGroup group, TextureData data) {
List<Atlas> atlases = (List<Atlas>) ATLASES.get(group); List<Atlas> atlases = (List<Atlas>) ATLASES.get(group);
if ( if (atlases.isEmpty() || !(atlases.get(atlases.size() - 1).canAddSprite(data))) {
atlases.isEmpty() ||
!(atlases.get(atlases.size() - 1).canAddSprite(data))
) {
Atlas newAtlas = new Atlas(group); Atlas newAtlas = new Atlas(group);
if (!newAtlas.canAddSprite(data)) { 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); atlases.add(newAtlas);
@ -202,6 +189,7 @@ public class Atlases {
}); });
} }
private Atlases() {} private Atlases() {
}
} }

View File

@ -6,6 +6,7 @@ import java.util.Map;
import ru.windcorp.progressia.common.resource.Resource; import ru.windcorp.progressia.common.resource.Resource;
import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class SimpleTextures { public class SimpleTextures {
@ -30,7 +31,8 @@ public class SimpleTextures {
new Sprite(new TexturePrimitive(data.getData())) new Sprite(new TexturePrimitive(data.getData()))
); );
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); CrashReports.report(e, "Problem with load texture");
return null;
} }
} }

View File

@ -24,6 +24,7 @@ import java.util.Arrays;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class TexturePrimitive implements OpenGLDeletable { public class TexturePrimitive implements OpenGLDeletable {
@ -89,7 +90,7 @@ public class TexturePrimitive implements OpenGLDeletable {
OpenGLObjectTracker.register(this); OpenGLObjectTracker.register(this);
if (handle < 0) { if (handle < 0) {
throw new RuntimeException("oops"); CrashReports.report(null, "Failed to create texture");
} }
} }

View File

@ -3,6 +3,8 @@ package ru.windcorp.progressia.client.localization;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.*; import java.util.*;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Localizer { public class Localizer {
private static final Localizer INSTANCE = new Localizer("assets/languages/", "en-US"); private static final Localizer INSTANCE = new Localizer("assets/languages/", "en-US");
@ -17,7 +19,7 @@ public class Localizer {
private final Collection<WeakReference<LocaleListener>> listeners = private final Collection<WeakReference<LocaleListener>> listeners =
Collections.synchronizedCollection(new LinkedList<>()); 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) { public Localizer(String langFolder) {
this.langFolder = langFolder; this.langFolder = langFolder;
this.langList = new Parser(langFolder + "lang_list.txt").parse(); this.langList = new Parser(langFolder + "lang_list.txt").parse();
@ -41,7 +43,7 @@ public class Localizer {
data = new Parser(langFolder + this.language + ".lang").parse(); data = new Parser(langFolder + this.language + ".lang").parse();
pokeListeners(language); pokeListeners(language);
} else { } 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) { private void pokeListeners(String newLanguage) {
//TODO extract as weak bus listener class // TODO extract as weak bus listener class
synchronized (listeners) { synchronized (listeners) {
Iterator<WeakReference<LocaleListener>> iterator = listeners.iterator(); Iterator<WeakReference<LocaleListener>> iterator = listeners.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {

View File

@ -3,6 +3,7 @@ package ru.windcorp.progressia.client.localization;
import ru.windcorp.jputil.chars.EscapeException; import ru.windcorp.jputil.chars.EscapeException;
import ru.windcorp.jputil.chars.Escaper; import ru.windcorp.jputil.chars.Escaper;
import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
@ -54,7 +55,7 @@ public class Parser {
if (c == '=') { if (c == '=') {
String key = ESCAPER.escape(stringBuilder.toString()); String key = ESCAPER.escape(stringBuilder.toString());
stringBuilder.setLength(0); stringBuilder.setLength(0);
rawData.read(); //skip a char rawData.read(); // skip a char
while (true) { while (true) {
code = rawData.read(); code = rawData.read();
if (code == -1) { if (code == -1) {
@ -80,7 +81,8 @@ public class Parser {
} }
} catch (IOException | EscapeException e) { } catch (IOException | EscapeException e) {
throw new RuntimeException(e); CrashReports.report(e, "Problems with parsing");
return null;
} }
return parsedData; return parsedData;
} }

View File

@ -7,6 +7,7 @@ import ru.windcorp.progressia.client.graphics.texture.TexturePrimitive;
import ru.windcorp.progressia.client.graphics.texture.TextureSettings; import ru.windcorp.progressia.client.graphics.texture.TextureSettings;
import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.common.util.NamespacedRegistry; import ru.windcorp.progressia.common.util.NamespacedRegistry;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class EntityRenderRegistry extends NamespacedRegistry<EntityRender> { public class EntityRenderRegistry extends NamespacedRegistry<EntityRender> {
@ -28,7 +29,8 @@ public class EntityRenderRegistry extends NamespacedRegistry<EntityRender> {
).getData() ).getData()
); );
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); CrashReports.report(e, "__DOC__ME__");
return null;
} }
} }

View File

@ -30,6 +30,7 @@ import com.google.common.io.CharStreams;
import ru.windcorp.progressia.Progressia; import ru.windcorp.progressia.Progressia;
import ru.windcorp.progressia.common.util.Named; import ru.windcorp.progressia.common.util.Named;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Resource extends Named { public class Resource extends Named {
@ -50,7 +51,8 @@ public class Resource extends Named {
try (Reader reader = getReader()) { try (Reader reader = getReader()) {
return CharStreams.toString(reader); return CharStreams.toString(reader);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); // TODO handle gracefully CrashReports.report(e, "__DOC__ME__");
return null;
} }
} }
@ -59,7 +61,8 @@ public class Resource extends Named {
try (InputStream stream = getInputStream()) { try (InputStream stream = getInputStream()) {
byteArray = ByteStreams.toByteArray(stream); byteArray = ByteStreams.toByteArray(stream);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); // TODO handle gracefully CrashReports.report(e, "__DOC__ME__");
return null;
} }
if (output == null || output.remaining() < byteArray.length) { if (output == null || output.remaining() < byteArray.length) {

View File

@ -4,6 +4,8 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.util.StringBuilderWriter; import org.apache.logging.log4j.core.util.StringBuilderWriter;
import ru.windcorp.jputil.chars.StringUtil;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -16,17 +18,16 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
public class CrashReportGenerator { public class CrashReports {
private CrashReportGenerator() {} private CrashReports() {
}
private static final Path CRASH_REPORTS_PATH = Paths.get("crash-reports"); private static final Path CRASH_REPORTS_PATH = Paths.get("crash-reports");
private static final Collection<ContextProvider> PROVIDERS = private static final Collection<ContextProvider> PROVIDERS = Collections.synchronizedCollection(new ArrayList<>());
Collections.synchronizedCollection(new ArrayList<>());
private static final Collection<Analyzer> ANALYZERS = private static final Collection<Analyzer> ANALYZERS = Collections.synchronizedCollection(new ArrayList<>());
Collections.synchronizedCollection(new ArrayList<>());
private static final Logger LOGGER = LogManager.getLogger("crash"); private static final Logger LOGGER = LogManager.getLogger("crash");
@ -34,11 +35,12 @@ public class CrashReportGenerator {
* <em>This method never returns.</em> * <em>This method never returns.</em>
* <p> * <p>
* TODO document * TODO document
*
* @param throwable * @param throwable
* @param messageFormat * @param messageFormat
* @param args * @param args
*/ */
public static void crash(Throwable throwable, String messageFormat, Object... args) { public static void report(Throwable throwable, String messageFormat, Object... args) {
StringBuilder output = new StringBuilder(); StringBuilder output = new StringBuilder();
appendContextProviders(output); appendContextProviders(output);
@ -59,11 +61,11 @@ public class CrashReportGenerator {
private static void appendContextProviders(StringBuilder output) { private static void appendContextProviders(StringBuilder output) {
// Do a local copy to avoid deadlocks -OLEGSHA // Do a local copy to avoid deadlocks -OLEGSHA
ContextProvider[] localProvidersCopy = ContextProvider[] localProvidersCopy = PROVIDERS.toArray(new ContextProvider[PROVIDERS.size()]);
PROVIDERS.toArray(new ContextProvider[PROVIDERS.size()]);
for (ContextProvider provider : localProvidersCopy) { for (ContextProvider provider : localProvidersCopy) {
if (provider == null) continue; if (provider == null)
continue;
addSeparator(output); addSeparator(output);
@ -94,18 +96,16 @@ public class CrashReportGenerator {
} }
} }
private static boolean appendAnalyzers( private static boolean appendAnalyzers(StringBuilder output, Throwable throwable, String messageFormat,
StringBuilder output, Object[] args) {
Throwable throwable, String messageFormat, Object[] args
) {
boolean analyzerResponsesExist = false; boolean analyzerResponsesExist = false;
// Do a local copy to avoid deadlocks -OLEGSHA // Do a local copy to avoid deadlocks -OLEGSHA
Analyzer[] localAnalyzersCopy = Analyzer[] localAnalyzersCopy = ANALYZERS.toArray(new Analyzer[ANALYZERS.size()]);
ANALYZERS.toArray(new Analyzer[ANALYZERS.size()]);
for (Analyzer analyzer : localAnalyzersCopy) { for (Analyzer analyzer : localAnalyzersCopy) {
if (analyzer == null) continue; if (analyzer == null)
continue;
String answer; String answer;
try { try {
@ -177,22 +177,19 @@ public class CrashReportGenerator {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss"); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss");
try { try {
if (!Files.exists(CRASH_REPORTS_PATH)) Files.createDirectory(CRASH_REPORTS_PATH); 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() + "/latest.log");
createFileForCrashReport(output, CRASH_REPORTS_PATH.toString() + "/crash-" + dateFormat.format(date) + ".log"); createFileForCrashReport(output,
CRASH_REPORTS_PATH.toString() + "/crash-" + dateFormat.format(date) + ".log");
} catch (Throwable t) { } catch (Throwable t) {
// Crash Report not created // Crash Report not created
} }
} }
private static void createFileForCrashReport(String buffer, String filename) { private static void createFileForCrashReport(String buffer, String filename) {
try ( try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(filename), StandardCharsets.UTF_8)) {
BufferedWriter writer = Files.newBufferedWriter(
Paths.get(filename),
StandardCharsets.UTF_8
)
) {
writer.write(buffer); writer.write(buffer);
} catch (IOException ex) { } catch (IOException ex) {
// Crash Report not created // Crash Report not created
@ -210,7 +207,6 @@ public class CrashReportGenerator {
private static void addSeparator(StringBuilder sb) { private static void addSeparator(StringBuilder sb) {
sb.append( sb.append(
// 80 chars // 80 chars
"--------------------------------------------------------------------------------" "--------------------------------------------------------------------------------").append("\n");
).append("\n");
} }
} }

View File

@ -7,6 +7,7 @@ import java.io.IOException;
import ru.windcorp.progressia.common.comms.packets.PacketWorldChange; import ru.windcorp.progressia.common.comms.packets.PacketWorldChange;
import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.state.IOContext;
import ru.windcorp.progressia.common.util.DataBuffer; import ru.windcorp.progressia.common.util.DataBuffer;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.WorldData;
public class PacketEntityChange extends PacketWorldChange { public class PacketEntityChange extends PacketWorldChange {
@ -43,17 +44,13 @@ public class PacketEntityChange extends PacketWorldChange {
EntityData entity = world.getEntity(getEntityId()); EntityData entity = world.getEntity(getEntityId());
if (entity == null) { if (entity == null) {
throw new RuntimeException( CrashReports.report(null, "Entity with ID %d not found", getEntityId());
"Entity with ID " + getEntityId() + " not found"
);
} }
try { try {
entity.read(getReader(), IOContext.COMMS); entity.read(getReader(), IOContext.COMMS);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException( CrashReports.report(e, "Entity could not be read");
"Entity could not be read", e
);
} }
} }

View File

@ -11,6 +11,7 @@ import ru.windcorp.progressia.common.comms.packets.PacketWorldChange;
import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.state.IOContext;
import ru.windcorp.progressia.common.util.LowOverheadCache; import ru.windcorp.progressia.common.util.LowOverheadCache;
import ru.windcorp.progressia.common.util.Vectors; 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.Coordinates;
import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockData;
@ -95,8 +96,7 @@ public class ImplementedChangeTracker implements Changer {
Vec3i blockInChunk = Vectors.grab3i(); Vec3i blockInChunk = Vectors.grab3i();
Coordinates.convertInWorldToInChunk(position, blockInChunk); Coordinates.convertInWorldToInChunk(position, blockInChunk);
List<TileData> tiles = world.getChunkByBlock(position) List<TileData> tiles = world.getChunkByBlock(position).getTiles(blockInChunk, face);
.getTiles(blockInChunk, face);
if (shouldAdd) { if (shouldAdd) {
tiles.add(tile); tiles.add(tile);
@ -134,7 +134,7 @@ public class ImplementedChangeTracker implements Changer {
try { try {
entity.write(packet.getWriter(), IOContext.COMMS); entity.write(packet.getWriter(), IOContext.COMMS);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); CrashReports.report(e, "__DOC__ME__");
} }
} }
@ -146,7 +146,7 @@ public class ImplementedChangeTracker implements Changer {
try { try {
entity.write(packet.getWriter(), IOContext.COMMS); entity.write(packet.getWriter(), IOContext.COMMS);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException("Entity could not be written", e); CrashReports.report(e, "Entity could not be written");
} }
} }