001/*
002 * Trident - A Multithreaded Server Alternative
003 * Copyright 2014 The TridentSDK Team
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package net.tridentsdk.util;
018
019import com.google.common.base.Function;
020import com.google.common.collect.Collections2;
021import net.tridentsdk.Trident;
022import net.tridentsdk.meta.ChatColor;
023import net.tridentsdk.plugin.Plugin;
024import net.tridentsdk.registry.Registered;
025import org.slf4j.Logger;
026import org.slf4j.Marker;
027
028import javax.annotation.Nullable;
029import java.util.Arrays;
030
031/**
032 * Represents a delegated logger
033 *
034 * @author The TridentSDK Team
035 * @since 0.4-alpha
036 */
037public class LoggerDelegate implements Logger {
038    private static final String[] ERRORS = {
039            "Aw, Mazen! Really?",
040            "I feel funny",
041            "9 + 10 does not equal 21",
042            "Dang",
043            "Tony Abbot, the fax didn't go through",
044            "This wasn't supposed to happen. It did anyways.",
045            "Houston, we have a problem",
046            "Oh great, a stacktrace. Can't we write good software for once?",
047            "Trust me this isn't a bug, it's a feature!",
048            "Pierre pls",
049            "Myth is extra salty today",
050            "Budgie, your NBT... It's leaking...",
051            "Vilsol is a Java developer? What?",
052            "gg Tigur",
053            "Orange? No, no, Trident is blue. Oh, Max?",
054            "Hey look, we got another one!",
055            "And this is the point where I give up",
056            "Indeed, there seems to be an error, m'lord!",
057            "I don't know how this happened, I thought black holes were sefe!",
058            "I promise* that this won't happen again! * Please read license agreement",
059            "I pronounce you owner and error, you may now report me.",
060            "So class, what have we learned today?",
061            "You saw nothing!",
062            "Quick hide! Did anyone see us?",
063    };
064    private final Logger logger;
065    
066    public LoggerDelegate(Logger logger) {
067        this.logger = logger;
068    }
069
070    private static String parse(String item) {
071        StringBuilder builder = new StringBuilder();
072        for (int i = 0; i < item.length(); i++) {
073            char c = item.charAt(i);
074            if (c == 'ยง') {
075                // Find the character after that
076                char esc = item.charAt(i + 1);
077                ChatColor color = ChatColor.of(esc);
078
079                // Not a real color, continue on
080                if (color == null) {
081                    builder.append(c);
082                } else {
083                    String s = ChatColor.consoleFormat(color);
084
085                    // Not a console color, append it anyways
086                    if ("".equals(s)) {
087                        builder.append(c);
088                    } else {
089                        // Append the console format instead of the chat color
090                        builder.append(parse(s));
091
092                        // Skip the next character, don't even append it
093                        i++;
094                    }
095                }
096            } else {
097                // No color escape, append normally
098                builder.append(c);
099            }
100        }
101
102        return builder.toString();
103    }
104
105    /**
106     * Formats the throwable
107     *
108     * @param throwable the throwable to format
109     */
110    public void error(Throwable throwable) {
111        StackTraceElement[] stackTrace = throwable.getStackTrace();
112
113        logger.error("========  BEGIN ERROR =========");
114
115        logger.error("");
116        String errorMessage = throwable.getMessage();
117
118        if (errorMessage == null || errorMessage.equals("null")) {
119            errorMessage = throwable.getClass().getSimpleName();
120        }
121
122        logger.error(ERRORS[(int) FastRandom.random(ERRORS.length - 1)]);
123        logger.error("");
124        logger.error("Error occurred in thread \"" + Thread.currentThread().getName() + "\": ");
125        logger.error(errorMessage);
126        logger.error("");
127        logger.error("======== Print Debug Information =========");
128        StackTraceElement main = stackTrace[0];
129        logger.error("Class:  " + main.getClassName());
130        logger.error("Method: " + main.getMethodName());
131        logger.error("Line:   " + (main.getLineNumber() > 0 ? main.getLineNumber() : "Native method"));
132        logger.error("======== End Debug Information =========");
133        logger.error("");
134        logger.error("======== Print Stacktrace =========");
135        for (StackTraceElement element : stackTrace) {
136            String className = element.getClassName();
137            if (className.contains("io.netty")) break;
138
139            logger.error("    at " + className + "." +
140                    element.getMethodName() + "(...) : " +
141                    (!element.isNativeMethod() ? element.getLineNumber() : "Native method"));
142        }
143        logger.error("======== End Stacktrace =========");
144        logger.error("");
145        logger.error("======== Print Server info =========");
146        logger.error("Trident version: " + Trident.version());
147        logger.error("Plugins:         " + Arrays.toString(
148                Collections2.transform(Registered.plugins(), new Function<Plugin, String>() {
149                    @Nullable @Override
150                    public String apply(Plugin plugin) {
151                        return plugin.description().name();
152                    }
153                }).toArray()));
154        logger.error("Java:            version " + System.getProperty("java.version") + " distributed by " +
155                System.getProperty("java.vendor"));
156        logger.error("OS:              running " +
157                System.getProperty("os.name") + " version " +
158                System.getProperty("os.version") + " " +
159                System.getProperty("os.arch"));
160        logger.error("======== End Server info =========");
161        logger.error("");
162        logger.error("========  END ERROR  =========");
163    }
164    
165    ///////////////////////////////////////// DELEGATE METHODS /////////////////////////////////////////
166
167    @Override
168    public String getName() {
169        return logger.getName();
170    }
171
172    @Override
173    public boolean isTraceEnabled() {
174        return logger.isTraceEnabled();
175    }
176
177    @Override
178    public void trace(String s) {
179        logger.trace(parse(s));
180    }
181
182    @Override
183    public void trace(String s, Object o) {
184        logger.trace(parse(s), o);
185    }
186
187    @Override
188    public void trace(String s, Object o, Object o1) {
189        logger.trace(parse(s), o, o1);
190    }
191
192    @Override
193    public void trace(String s, Object... objects) {
194        logger.trace(parse(s), objects);
195    }
196
197    @Override
198    public void trace(String s, Throwable throwable) {
199        logger.trace(parse(s), throwable);
200    }
201
202    @Override
203    public boolean isTraceEnabled(Marker marker) {
204        return logger.isTraceEnabled(marker);
205    }
206
207    @Override
208    public void trace(Marker marker, String s) {
209        logger.trace(marker, parse(s));
210    }
211
212    @Override
213    public void trace(Marker marker, String s, Object o) {
214        logger.trace(marker, parse(s));
215    }
216
217    @Override
218    public void trace(Marker marker, String s, Object o, Object o1) {
219        logger.trace(marker, parse(s), o, o1);
220    }
221
222    @Override
223    public void trace(Marker marker, String s, Object... objects) {
224        logger.trace(marker, parse(s), objects);
225    }
226
227    @Override
228    public void trace(Marker marker, String s, Throwable throwable) {
229        logger.trace(marker, parse(s), throwable);
230    }
231
232    @Override
233    public boolean isDebugEnabled() {
234        return logger.isDebugEnabled();
235    }
236
237    @Override
238    public void debug(String s) {
239        logger.debug(parse(s));
240    }
241
242    @Override
243    public void debug(String s, Object o) {
244        logger.debug(parse(s), o);
245    }
246
247    @Override
248    public void debug(String s, Object o, Object o1) {
249        logger.debug(parse(s), o);
250    }
251
252    @Override
253    public void debug(String s, Object... objects) {
254        logger.debug(parse(s), objects);
255    }
256
257    @Override
258    public void debug(String s, Throwable throwable) {
259        logger.debug(parse(s), throwable);
260    }
261
262    @Override
263    public boolean isDebugEnabled(Marker marker) {
264        return logger.isDebugEnabled(marker);
265    }
266
267    @Override
268    public void debug(Marker marker, String s) {
269        logger.debug(marker, parse(s));
270    }
271
272    @Override
273    public void debug(Marker marker, String s, Object o) {
274        logger.debug(marker, parse(s), o);
275    }
276
277    @Override
278    public void debug(Marker marker, String s, Object o, Object o1) {
279        logger.debug(marker, parse(s), o, o1);
280    }
281
282    @Override
283    public void debug(Marker marker, String s, Object... objects) {
284        logger.debug(marker, parse(s), objects);
285    }
286
287    @Override
288    public void debug(Marker marker, String s, Throwable throwable) {
289        logger.debug(marker, parse(s), throwable);
290    }
291
292    @Override
293    public boolean isInfoEnabled() {
294        return logger.isInfoEnabled();
295    }
296
297    @Override
298    public void info(String s) {
299        logger.info(parse(s));
300    }
301
302    @Override
303    public void info(String s, Object o) {
304        logger.info(parse(s), o);
305    }
306
307    @Override
308    public void info(String s, Object o, Object o1) {
309        logger.info(parse(s), o, o1);
310    }
311
312    @Override
313    public void info(String s, Object... objects) {
314        logger.info(parse(s), objects);
315    }
316
317    @Override
318    public void info(String s, Throwable throwable) {
319        logger.info(parse(s), throwable);
320    }
321
322    @Override
323    public boolean isInfoEnabled(Marker marker) {
324        return logger.isInfoEnabled(marker);
325    }
326
327    @Override
328    public void info(Marker marker, String s) {
329        logger.info(marker, parse(s));
330    }
331
332    @Override
333    public void info(Marker marker, String s, Object o) {
334        logger.info(marker, parse(s), o);
335    }
336
337    @Override
338    public void info(Marker marker, String s, Object o, Object o1) {
339        logger.info(marker, parse(s), o, o1);
340    }
341
342    @Override
343    public void info(Marker marker, String s, Object... objects) {
344        logger.info(marker, parse(s), objects);
345    }
346
347    @Override
348    public void info(Marker marker, String s, Throwable throwable) {
349        logger.info(marker, parse(s), throwable);
350    }
351
352    @Override
353    public boolean isWarnEnabled() {
354        return logger.isWarnEnabled();
355    }
356
357    @Override
358    public void warn(String s) {
359        logger.warn(parse(s));
360    }
361
362    @Override
363    public void warn(String s, Object o) {
364        logger.warn(parse(s), o);
365    }
366
367    @Override
368    public void warn(String s, Object... objects) {
369        logger.warn(parse(s), objects);
370    }
371
372    @Override
373    public void warn(String s, Object o, Object o1) {
374        logger.warn(parse(s), o, o1);
375    }
376
377    @Override
378    public void warn(String s, Throwable throwable) {
379        logger.warn(parse(s), throwable);
380    }
381
382    @Override
383    public boolean isWarnEnabled(Marker marker) {
384        return logger.isWarnEnabled();
385    }
386
387    @Override
388    public void warn(Marker marker, String s) {
389        logger.warn(marker, parse(s));
390    }
391
392    @Override
393    public void warn(Marker marker, String s, Object o) {
394        logger.warn(marker, parse(s), o);
395    }
396
397    @Override
398    public void warn(Marker marker, String s, Object o, Object o1) {
399        logger.warn(marker, parse(s), o, o1);
400    }
401
402    @Override
403    public void warn(Marker marker, String s, Object... objects) {
404        logger.warn(marker, parse(s), objects);
405    }
406
407    @Override
408    public void warn(Marker marker, String s, Throwable throwable) {
409        logger.warn(marker, parse(s), throwable);
410    }
411
412    @Override
413    public boolean isErrorEnabled() {
414        return logger.isErrorEnabled();
415    }
416
417    @Override
418    public void error(String s) {
419        logger.error(parse(s));
420    }
421
422    @Override
423    public void error(String s, Object o) {
424        logger.error(parse(s), o);
425    }
426
427    @Override
428    public void error(String s, Object o, Object o1) {
429        logger.error(parse(s), o, o1);
430    }
431
432    @Override
433    public void error(String s, Object... objects) {
434        logger.error(parse(s), objects);
435    }
436
437    @Override
438    public void error(String s, Throwable throwable) {
439        logger.error(parse(s), throwable);
440    }
441
442    @Override
443    public boolean isErrorEnabled(Marker marker) {
444        return logger.isErrorEnabled(marker);
445    }
446
447    @Override
448    public void error(Marker marker, String s) {
449        logger.error(marker, parse(s));
450    }
451
452    @Override
453    public void error(Marker marker, String s, Object o) {
454        logger.error(marker, parse(s), o);
455    }
456
457    @Override
458    public void error(Marker marker, String s, Object o, Object o1) {
459        logger.error(marker, parse(s), o, o1);
460    }
461
462    @Override
463    public void error(Marker marker, String s, Object... objects) {
464        logger.error(marker, parse(s), objects);
465    }
466
467    @Override
468    public void error(Marker marker, String s, Throwable throwable) {
469        logger.error(marker, parse(s), throwable);
470    }
471}