mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-06 07:32:46 +00:00
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.l2jserver.model.id.template;
|
||||
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.model.id.TemplateID;
|
||||
@@ -40,6 +42,7 @@ public class ActorTemplateID<T extends ActorTemplate<?>> extends TemplateID<T, I
|
||||
}
|
||||
|
||||
@Override
|
||||
@XmlTransient
|
||||
public T getTemplate() {
|
||||
return templateService.getTemplate(this);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.l2jserver.model.id.template;
|
||||
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.model.id.TemplateID;
|
||||
@@ -27,6 +29,7 @@ import com.l2jserver.service.game.template.TemplateService;
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlTransient
|
||||
public class ItemTemplateID extends TemplateID<ItemTemplate, Integer> {
|
||||
/**
|
||||
* The template service
|
||||
|
||||
@@ -16,20 +16,29 @@
|
||||
*/
|
||||
package com.l2jserver.model.id.template;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.model.id.TemplateID;
|
||||
import com.l2jserver.model.template.NPCTemplate;
|
||||
import com.l2jserver.service.game.template.TemplateService;
|
||||
import com.l2jserver.util.jaxb.NPCTemplateIDAdapter;
|
||||
|
||||
/**
|
||||
* An {@link TemplateID} instance representing an {@link NPCTemplate} object
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlJavaTypeAdapter(value = NPCTemplateIDAdapter.class)
|
||||
public class NPCTemplateID extends ActorTemplateID<NPCTemplate> {
|
||||
@Inject
|
||||
protected NPCTemplateID(@Assisted int id, TemplateService templateService) {
|
||||
public NPCTemplateID(@Assisted int id, TemplateService templateService) {
|
||||
super(id, templateService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPCTemplate getTemplate() {
|
||||
return super.getTemplate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,18 +16,22 @@
|
||||
*/
|
||||
package com.l2jserver.model.id.template;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.model.id.TemplateID;
|
||||
import com.l2jserver.model.template.SkillTemplate;
|
||||
import com.l2jserver.model.template.TeleportationTemplate;
|
||||
import com.l2jserver.service.game.template.TemplateService;
|
||||
import com.l2jserver.util.jaxb.TeleportationTemplateIDAdapter;
|
||||
|
||||
/**
|
||||
* An {@link TemplateID} instance representing an {@link SkillTemplate} object
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlJavaTypeAdapter(TeleportationTemplateIDAdapter.class)
|
||||
public class TeleportationTemplateID extends
|
||||
TemplateID<TeleportationTemplate, String> {
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,8 @@ import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import org.eclipse.persistence.oxm.annotations.XmlCDATA;
|
||||
|
||||
import com.l2jserver.model.id.template.ItemTemplateID;
|
||||
import com.l2jserver.model.id.template.NPCTemplateID;
|
||||
import com.l2jserver.model.id.template.TeleportationTemplateID;
|
||||
@@ -87,11 +89,11 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
protected ActorSex sex = null;
|
||||
|
||||
@XmlAttribute(name = "attackable")
|
||||
protected Boolean attackable = null;
|
||||
protected boolean attackable;
|
||||
@XmlAttribute(name = "targetable")
|
||||
protected Boolean targetable = null;
|
||||
protected boolean targetable;
|
||||
@XmlAttribute(name = "aggressive")
|
||||
protected Boolean aggressive = null;
|
||||
protected boolean aggressive;
|
||||
|
||||
@XmlElement(name = "stats")
|
||||
protected NPCStatsMetadata stats = null;
|
||||
@@ -246,7 +248,7 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
@XmlType(namespace = "npc")
|
||||
public static class TeleportRegion {
|
||||
@XmlAttribute(name = "id")
|
||||
@XmlJavaTypeAdapter(TeleportationTemplateIDAdapter.class)
|
||||
@XmlJavaTypeAdapter(value = TeleportationTemplateIDAdapter.class)
|
||||
protected TeleportationTemplateID id;
|
||||
@XmlAttribute(name = "price")
|
||||
protected int price = 0;
|
||||
@@ -295,6 +297,7 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
@XmlAttribute(name = "id")
|
||||
protected String id = null;
|
||||
@XmlValue
|
||||
@XmlCDATA
|
||||
protected String html = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,10 +93,16 @@ public class AbstractNPCController implements NPCController {
|
||||
* @return the html code
|
||||
*/
|
||||
protected String getHTML(NPC npc, String id) {
|
||||
// id correction - on l2j default chat is also "0".
|
||||
if ("0".equals(id)) // avoid NullPointerException
|
||||
id = null;
|
||||
|
||||
final NPCTemplate template = npc.getTemplate();
|
||||
String html = template.getHTML(id);
|
||||
if (html == null)
|
||||
return null;
|
||||
// TODO use an decent template engine
|
||||
return template.getHTML(id).replaceAll("%objectId%",
|
||||
npc.getID().getID().toString());
|
||||
return html.replaceAll("%objectId%", npc.getID().getID().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,7 +57,7 @@ public class ServiceManager {
|
||||
}
|
||||
logger = LoggerFactory.getLogger(ServiceManager.class);
|
||||
}
|
||||
|
||||
|
||||
public <T extends Service> T get(Class<T> serviceClass) {
|
||||
return injector.getInstance(serviceClass);
|
||||
}
|
||||
@@ -81,6 +81,10 @@ public class ServiceManager {
|
||||
logger.error("{}: Error starting service: {}",
|
||||
serviceClass.getCanonicalName(), e);
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
logger.error("{}: Error starting service: {}",
|
||||
serviceClass.getCanonicalName(), e);
|
||||
throw new ServiceStartException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.inject.Inject;
|
||||
@@ -55,6 +57,8 @@ import com.l2jserver.util.jaxb.TeleportationTemplateIDAdapter;
|
||||
@Depends({ LoggingService.class, ConfigurationService.class })
|
||||
public class XMLTemplateService extends AbstractService implements
|
||||
TemplateService {
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final XMLTemplateServiceConfiguration config;
|
||||
private final NPCTemplateIDAdapter npcTemplateIdAdapter;
|
||||
private final ItemTemplateIDAdapter itemTemplateIdAdapter;
|
||||
@@ -83,9 +87,12 @@ public class XMLTemplateService extends AbstractService implements
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
try {
|
||||
log.debug("Creating JAXBContext instance");
|
||||
context = JAXBContext.newInstance(CharacterTemplate.class,
|
||||
NPCTemplate.class, ItemTemplate.class,
|
||||
TeleportationTemplateContainer.class);
|
||||
|
||||
log.debug("Creating Unmarshaller instance");
|
||||
unmarshaller = context.createUnmarshaller();
|
||||
|
||||
unmarshaller.setAdapter(NPCTemplateIDAdapter.class,
|
||||
@@ -101,7 +108,9 @@ public class XMLTemplateService extends AbstractService implements
|
||||
Collection<File> files = FileUtils
|
||||
.listFiles(config.getTemplateDirectory(),
|
||||
new String[] { "xml" }, true);
|
||||
log.debug("Located {} XML template files", files.size());
|
||||
for (final File file : files) {
|
||||
log.debug("Loading template {}", file);
|
||||
loadTemplate(file);
|
||||
}
|
||||
TeleportationTemplateContainer container = (TeleportationTemplateContainer) unmarshaller
|
||||
@@ -111,6 +120,8 @@ public class XMLTemplateService extends AbstractService implements
|
||||
templates.put(template.getID(), template);
|
||||
}
|
||||
} catch (JAXBException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
throw new ServiceStartException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ public class XMLMappingTest {
|
||||
//
|
||||
// System.out.println("Took " + ((end - start) / 1000) + " seconds");
|
||||
|
||||
final TeleportationTemplate t = (TeleportationTemplate) u
|
||||
.unmarshal(new File("data/templates/teleports.xml"));
|
||||
final NPCTemplate t = (NPCTemplate) u
|
||||
.unmarshal(new File("data/templates/npc/teleporter/30059-Trisha.xml"));
|
||||
System.out.println(t.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,10 @@ import com.l2jserver.model.id.template.provider.ItemTemplateIDProvider;
|
||||
public class ItemTemplateIDAdapter extends XmlAdapter<Integer, ItemTemplateID> {
|
||||
private final ItemTemplateIDProvider provider;
|
||||
|
||||
public ItemTemplateIDAdapter() {
|
||||
provider = null;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ItemTemplateIDAdapter(ItemTemplateIDProvider provider) {
|
||||
this.provider = provider;
|
||||
@@ -39,6 +43,8 @@ public class ItemTemplateIDAdapter extends XmlAdapter<Integer, ItemTemplateID> {
|
||||
public ItemTemplateID unmarshal(Integer v) throws Exception {
|
||||
if (v == 0)
|
||||
return null;
|
||||
if(provider == null)
|
||||
return new ItemTemplateID(v, null);
|
||||
return provider.createID(v);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@ import com.l2jserver.model.id.template.provider.NPCTemplateIDProvider;
|
||||
public class NPCTemplateIDAdapter extends XmlAdapter<Integer, NPCTemplateID> {
|
||||
private final NPCTemplateIDProvider provider;
|
||||
|
||||
public NPCTemplateIDAdapter() {
|
||||
provider = null;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public NPCTemplateIDAdapter(NPCTemplateIDProvider provider) {
|
||||
this.provider = provider;
|
||||
@@ -40,6 +44,8 @@ public class NPCTemplateIDAdapter extends XmlAdapter<Integer, NPCTemplateID> {
|
||||
public NPCTemplateID unmarshal(Integer v) throws Exception {
|
||||
if (v == 0)
|
||||
return null;
|
||||
if (provider == null)
|
||||
return new NPCTemplateID(v, null);
|
||||
return provider.createID(v);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,10 @@ public class TeleportationTemplateIDAdapter extends
|
||||
XmlAdapter<String, TeleportationTemplateID> {
|
||||
private final TeleportationTemplateIDProvider provider;
|
||||
|
||||
public TeleportationTemplateIDAdapter() {
|
||||
provider = null;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public TeleportationTemplateIDAdapter(
|
||||
TeleportationTemplateIDProvider provider) {
|
||||
@@ -42,6 +46,8 @@ public class TeleportationTemplateIDAdapter extends
|
||||
public TeleportationTemplateID unmarshal(String v) throws Exception {
|
||||
if (v == null)
|
||||
return null;
|
||||
if (provider == null)
|
||||
return new TeleportationTemplateID(v, null);
|
||||
return provider.createID(v);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,24 +17,32 @@
|
||||
package com.l2jserver.model.template;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.MarshalException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import javax.xml.bind.SchemaOutputResolver;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import com.l2jserver.model.id.template.ItemTemplateID;
|
||||
import com.l2jserver.model.id.template.NPCTemplateID;
|
||||
import com.l2jserver.model.template.NPCTemplate.Chat;
|
||||
import com.l2jserver.model.template.NPCTemplate.DropItemMetadata;
|
||||
import com.l2jserver.model.template.NPCTemplate.NPCInformationMetadata;
|
||||
import com.l2jserver.model.template.NPCTemplate.NPCInformationMetadata.CollisionMetadata;
|
||||
@@ -49,22 +57,33 @@ import com.l2jserver.model.template.NPCTemplate.NPCInformationMetadata.NPCStatsM
|
||||
import com.l2jserver.model.template.NPCTemplate.NPCInformationMetadata.NPCStatsMetadata.MoveMetadata;
|
||||
import com.l2jserver.model.template.NPCTemplate.NPCInformationMetadata.NPCStatsMetadata.Stat;
|
||||
import com.l2jserver.model.template.NPCTemplate.NPCInformationMetadata.NPCTitleMetadata;
|
||||
import com.l2jserver.model.template.NPCTemplate.TalkMetadata;
|
||||
import com.l2jserver.model.world.Actor.ActorSex;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
|
||||
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
|
||||
|
||||
public class NPCTemplateConverter {
|
||||
private static final String JDBC_URL = "jdbc:mysql://localhost/l2j-old";
|
||||
private static final String JDBC_USERNAME = "l2j";
|
||||
private static final String JDBC_PASSWORD = "changeme";
|
||||
private static final File L2J_HTML_FOLDER = new File(
|
||||
"../L2J_DataPack_BETA/data/html");
|
||||
|
||||
private static List<NPCTemplate> templates = CollectionFactory.newList();
|
||||
private static Collection<File> htmlScannedFiles;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void main(String[] args) throws SQLException, IOException,
|
||||
ClassNotFoundException, JAXBException {
|
||||
Class.forName("com.mysql.jdbc.Driver");
|
||||
final File target = new File("generated/template");
|
||||
final File target = new File("data/templates");
|
||||
|
||||
System.out.println("Generating template classes...");
|
||||
System.out.println("Scaning legacy HTML files...");
|
||||
htmlScannedFiles = FileUtils.listFiles(L2J_HTML_FOLDER, new String[] {
|
||||
"html", "htm" }, true);
|
||||
|
||||
System.out.println("Generating template XML files...");
|
||||
|
||||
final JAXBContext c = JAXBContext.newInstance(NPCTemplate.class);
|
||||
c.generateSchema(new SchemaOutputResolver() {
|
||||
@@ -101,37 +120,54 @@ public class NPCTemplateConverter {
|
||||
final File file = new File(target, "npc/"
|
||||
+ folder
|
||||
+ "/"
|
||||
+ t.id
|
||||
+ t.id.getID()
|
||||
+ (t.info.nameMetadata != null ? "-"
|
||||
+ camelCase(t.info.nameMetadata.name) : "")
|
||||
+ ".xml");
|
||||
file.getParentFile().mkdirs();
|
||||
templates.add(t);
|
||||
|
||||
// m.marshal(t, file);
|
||||
|
||||
// m.marshal(t, System.out);
|
||||
// if (t.id.getID() == 30059) {
|
||||
// m.marshal(t, getXMLSerializer(System.out));
|
||||
// System.exit(0);
|
||||
// }
|
||||
|
||||
try {
|
||||
m.marshal(t, getXMLSerializer(new FileOutputStream(file)));
|
||||
} catch (MarshalException e) {
|
||||
System.err
|
||||
.println("Could not generate XML template file for "
|
||||
+ t.getName() + " - " + t.getID());
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Generated " + templates.size() + " templates");
|
||||
|
||||
System.gc();
|
||||
System.out.println("Free: " + Runtime.getRuntime().freeMemory()
|
||||
/ 1024 / 1024 + " MB");
|
||||
System.out.println("Total: " + Runtime.getRuntime().totalMemory()
|
||||
/ 1024 / 1024 + " MB");
|
||||
System.out.println("Used: "
|
||||
+ (Runtime.getRuntime().totalMemory() - Runtime
|
||||
.getRuntime().freeMemory()) / 1024 / 1024 + " MB");
|
||||
System.out.println("Max: " + Runtime.getRuntime().maxMemory()
|
||||
/ 1024 / 1024 + " MB");
|
||||
System.out.println("Free: "
|
||||
+ FileUtils.byteCountToDisplaySize(Runtime.getRuntime()
|
||||
.freeMemory()));
|
||||
System.out.println("Total: "
|
||||
+ FileUtils.byteCountToDisplaySize(Runtime.getRuntime()
|
||||
.totalMemory()));
|
||||
System.out
|
||||
.println("Used: "
|
||||
+ FileUtils.byteCountToDisplaySize(Runtime
|
||||
.getRuntime().totalMemory()
|
||||
- Runtime.getRuntime().freeMemory()));
|
||||
System.out.println("Max: "
|
||||
+ FileUtils.byteCountToDisplaySize(Runtime.getRuntime()
|
||||
.maxMemory()));
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static NPCTemplate fillNPC(ResultSet rs) throws SQLException {
|
||||
private static NPCTemplate fillNPC(ResultSet rs) throws SQLException,
|
||||
IOException {
|
||||
final NPCTemplate template = new NPCTemplate();
|
||||
template.id = null;
|
||||
template.id = new NPCTemplateID(rs.getInt("idTemplate"), null);
|
||||
template.type = createParentType(rs.getString("type"));
|
||||
template.info = new NPCInformationMetadata();
|
||||
|
||||
@@ -214,9 +250,9 @@ public class NPCTemplateConverter {
|
||||
template.info.collision.height = rs.getDouble("collision_height");
|
||||
|
||||
// TODO import teleporter data
|
||||
// TODO import html files
|
||||
|
||||
template.droplist = fillDropList(rs, template.id.getID());
|
||||
template.talk = fillHtmlChat(template.id.getID());
|
||||
|
||||
return template;
|
||||
}
|
||||
@@ -245,6 +281,33 @@ public class NPCTemplateConverter {
|
||||
return drops;
|
||||
}
|
||||
|
||||
private static TalkMetadata fillHtmlChat(int npcId) throws IOException {
|
||||
final TalkMetadata talk = new TalkMetadata();
|
||||
talk.defaultChat = "default";
|
||||
talk.chats = CollectionFactory.newList();
|
||||
for (final File file : htmlScannedFiles) {
|
||||
String id = null;
|
||||
if (file.getName().startsWith(npcId + "-")) {
|
||||
int preffixLength = (npcId + "-").length();
|
||||
id = file.getName().substring(preffixLength,
|
||||
file.getName().indexOf("."));
|
||||
} else if (file.getName().startsWith(npcId + ".")) {
|
||||
id = "default";
|
||||
}
|
||||
if (id != null && !file.getAbsolutePath().contains("/half/")
|
||||
&& !file.getAbsolutePath().contains("/free/")) {
|
||||
Chat chat = new Chat();
|
||||
chat.id = id;
|
||||
chat.html = FileUtils.readFileToString(file);
|
||||
talk.chats.add(chat);
|
||||
}
|
||||
}
|
||||
|
||||
if (talk.chats.size() == 0)
|
||||
return null;
|
||||
return talk;
|
||||
}
|
||||
|
||||
private static String camelCase(String c) {
|
||||
Pattern p = Pattern.compile("[a-zA-Z0-9]+");
|
||||
Matcher m = p.matcher(c.replaceAll("_", " ").replaceAll("\\.", " "));
|
||||
@@ -285,4 +348,26 @@ public class NPCTemplateConverter {
|
||||
return "misc";
|
||||
return l2j.toLowerCase();
|
||||
}
|
||||
|
||||
private static XMLSerializer getXMLSerializer(OutputStream w) {
|
||||
// configure an OutputFormat to handle CDATA
|
||||
OutputFormat of = new OutputFormat();
|
||||
|
||||
// specify which of your elements you want to be handled as CDATA.
|
||||
// The use of the '^' between the namespaceURI and the localname
|
||||
// seems to be an implementation detail of the xerces code.
|
||||
// When processing xml that doesn't use namespaces, simply omit the
|
||||
// namespace prefix as shown in the third CDataElement below.
|
||||
of.setCDataElements(new String[] { "^chat" });
|
||||
|
||||
// set any other options you'd like
|
||||
of.setPreserveSpace(false);
|
||||
of.setIndenting(true);
|
||||
|
||||
// create the serializer
|
||||
XMLSerializer serializer = new XMLSerializer(of);
|
||||
serializer.setOutputByteStream(w);
|
||||
|
||||
return serializer;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user