private static void processPacket( PacketType packet, JPackage dirPackage, JCodeModel codeModel, boolean fromClient) throws JClassAlreadyExistsException { // get the packet info String packetName = (packet.getInfo() == null || packet.getInfo().getName() == null) ? "Unknown" : packet.getInfo().getName(); String packetNamePrefixed = "P" + String.format("%03d", packet.getHeader()) + "_" + packetName; String packetDescription = (packet.getInfo() == null || packet.getInfo().getDescription() == null || packet.getInfo().getDescription().isEmpty()) ? "" : "\n" + WordUtils.wrap(packet.getInfo().getDescription(), /* maximumLength */ 50); JDefinedClass packetClass = dirPackage._class(JMod.FINAL | JMod.PUBLIC, packetNamePrefixed)._extends(GWMessage.class); LOGGER.info("+-Processing packet: {}", packetNamePrefixed); LOGGER.debug("|+-Packet description: {}", packetDescription); StringBuilder packetJavadoc = new StringBuilder("Auto-generated by PacketCodeGen.").append(packetDescription); JDocComment jDocComment = packetClass.javadoc(); jDocComment.add(packetJavadoc.toString()); AtomicInteger numberOfUnknowns = new AtomicInteger(); // unknown field number // get all fields in this packet for (FieldType field : packet.getField()) { processField(field, packetClass, codeModel, numberOfUnknowns, fromClient); } // generate the header method JMethod headerMeth = packetClass.method(JMod.PUBLIC, short.class, "getHeader"); headerMeth.annotate(Override.class); headerMeth.body()._return(JExpr.lit(packet.getHeader().intValue())); // generate getters, setters for (JFieldVar fieldVar : packetClass.fields().values()) { processAccessors(fieldVar, packetClass, fromClient); } // generate the toString method processToString(packetClass, codeModel); }
private static void processField( FieldType field, JDefinedClass packetClass, JCodeModel codeModel, AtomicInteger numberOfUnknowns, boolean fromClient) throws JClassAlreadyExistsException { boolean isNested = (field.getType() == PacketSimpleTypes.OPTIONAL) || (field.getType() == PacketSimpleTypes.ARRAY_STATIC) || (field.getType() == PacketSimpleTypes.ARRAY_VAR_SMALL) || (field.getType() == PacketSimpleTypes.ARRAY_VAR_BIG); boolean isArray = (field.getType() == PacketSimpleTypes.BUFFER_STATIC) || (field.getType() == PacketSimpleTypes.BUFFER_VAR_SMALL) || (field.getType() == PacketSimpleTypes.BUFFER_VAR_BIG) || (isNested && (field.getType() != PacketSimpleTypes.OPTIONAL)); boolean isStaticLength = (isArray) && ((field.getType() == PacketSimpleTypes.ARRAY_STATIC) || (field.getType() == PacketSimpleTypes.BUFFER_STATIC)); // length is either not set for non arrays and static arrays, // its 1byte for small stuff and 2bytes for big stuff. int prefixLength = (!isArray || isStaticLength) ? -1 : (field.getType() == PacketSimpleTypes.ARRAY_VAR_SMALL) || (field.getType() == PacketSimpleTypes.BUFFER_VAR_SMALL) ? 1 : 2; String name = ""; if (field.getInfo() == null || field.getInfo().getName() == null) { // check if we got special fields... if (field.getType() == PacketSimpleTypes.AGENTID) { name = "AgentID"; } else if (field.getType() == PacketSimpleTypes.OPTIONAL) { name = "Optional"; } else { name = "Unknown"; } name += numberOfUnknowns.incrementAndGet(); } else { name = field.getInfo().getName(); } String fieldName = WordUtils.uncapitalize(name); String fieldDescription = (field.getInfo() == null || field.getInfo().getDescription() == null || field.getInfo().getDescription().isEmpty()) ? "" : "\n" + WordUtils.wrap(field.getInfo().getDescription(), /* maximumLength */ 50); JType fieldType; if (isNested) { JDefinedClass nestedClass = packetClass ._class(JMod.FINAL | JMod.STATIC | JMod.PUBLIC, "Nested" + name) ._implements(NestedMarker.class); AtomicInteger numberOfUnknownsNested = new AtomicInteger(); for (FieldType nested : field.getField()) { processField(nested, nestedClass, codeModel, numberOfUnknownsNested, fromClient); } // generate getters, setters for (JFieldVar fieldVar : nestedClass.fields().values()) { processAccessors(fieldVar, nestedClass, fromClient); } processToString(nestedClass, codeModel); // nested classes are either arrays or optional... // meaning we will later have to test if they are null before reading/writing fieldType = isArray ? nestedClass.array() : nestedClass; } else { Class<?> fieldClass = convertFieldTypeToClass(field); fieldType = codeModel._ref(fieldClass); } LOGGER.debug("|+-Processing field: {}, of type: {}", fieldName, fieldType); // add the field JFieldVar packetField = packetClass.field(JMod.PRIVATE, fieldType, fieldName); if (fieldDescription != null && !fieldDescription.trim().equals("")) { JDocComment jDocComment = packetField.javadoc(); jDocComment.add(fieldDescription); } // and dont forget array annotations if necessary if (isArray) { int size = (int) (field.getElements() == null ? -1 : field.getElements()); packetField .annotate(IsArray.class) .param("constant", isStaticLength) .param("size", size) .param("prefixLength", prefixLength); } // or any special annotations if (field.getType() == PacketSimpleTypes.LONG) { packetField.annotate(IsInt64.class); } if (field.getType() == PacketSimpleTypes.VARINT) { packetField.annotate(IsVarInt.class); } if (field.getType() == PacketSimpleTypes.ASCII) { packetField.annotate(IsASCII.class); } }