Well, I was bored and was trying out some techniques and just messing around. Well, I decided that my application was going to be multi-threaded, what do you think of this kind of multi-threaded idea. This can be used for several things.
- Context data startup
- Player loading/saving
- Networking (Not needed for netty)
If you have any ideas on how I can improve, let me know!
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="server_thread">com/thomaslegodais/aura/thread/impl/ContextServerThread.java</entry>
</properties>
Code:
/*
An free -- open-source -- RuneScape emulator.
Copyright (C) 2012, Thomas Le Godais <[email protected]>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.thomaslegodais.aura;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Properties;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import com.thomaslegodais.aura.net.GameChannelPipelineFactory;
import com.thomaslegodais.aura.thread.AbstractServerThread;
import com.thomaslegodais.aura.util.ConsoleLogger;
/**
* The main application entry point. This class is used to load all of the
* {@link AbstractServerThread}'s from the {@link Properties} file. So in lames:
* gets everything up n' and running!
*
* <p>
* The main purpose of this class will be to perform 2 main priority functions.
* The first will be to load all of the {@link AbstractServerThread}s. And, the
* second one will to be successfully bind the server to a new
* {@link InetSocketAddress}. We do not run the networking on its own thread,
* since <b>Netty.io</b> networking already does that itself.
* </p>
*
* @author Thomas Le Godais <[email protected]>
*/
public class Main {
/**
* The {@link Executor} used for performing networking actions.
*/
private static final Executor exc = Executors.newCachedThreadPool();
/**
* The main entry point of the application, this is where everything that
* was mentioned gets up and running!
*
* @param args The command line arguments.
*/
@SuppressWarnings("unchecked")
public static void main(String... args) {
try {
System.setOut(new ConsoleLogger(System.out));
System.setErr(new ConsoleLogger(System.err));
System.out.println("Bootstrapping Aura emulator...");
Properties properties = new Properties();
properties.loadFromXML(new FileInputStream("./data/server-threads.xml"));
String serverThreadName = properties.getProperty("server_thread");
String fixedThreadName = serverThreadName = serverThreadName.replaceAll("/", ".").replace(".java", "");
String[] threadRegex = null;
if(fixedThreadName.contains(","))
threadRegex = fixedThreadName.split(",");
ConcurrentLinkedQueue<Class<AbstractServerThread>> serverThreads = new ConcurrentLinkedQueue<Class<AbstractServerThread>>();
if(threadRegex != null)
for(int i = 0; i < threadRegex.length; i++)
serverThreads.offer((Class<AbstractServerThread>) Class.forName(threadRegex[i]));
else
serverThreads.offer((Class<AbstractServerThread>) Class.forName(fixedThreadName));
for(Class<AbstractServerThread> threadClass : serverThreads) {
AbstractServerThread serverThread = threadClass.newInstance();
if(serverThread == null)
throw new RuntimeException("Specifed thread is NULL!");
new Thread(serverThread).start();
}
System.out.println("Now running " + serverThreads.size() + " server threads, total active threads [active=" + Thread.activeCount() + "]");
} catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.setFactory(new NioServerSocketChannelFactory(exc, exc));
bootstrap.setPipelineFactory(new GameChannelPipelineFactory());
bootstrap.bind(new InetSocketAddress(43594));
System.out.println("Successfully bootstrapped Aura!");
}
}
Code:
/*
An free -- open-source -- RuneScape emulator.
Copyright (C) 2012, Thomas Le Godais <[email protected]>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.thomaslegodais.aura.thread;
/**
* An {@link Thread} that is used to represent an individual thread in the server.
* @author Thomas Le Godais <[email protected]>
*/
public abstract class AbstractServerThread extends Thread implements Runnable {
/**
* The name of the thread we're creating.
*/
private String threadName;
/**
* Constructs a new {@code AbstractServerThread} instance.
* @param threadName The name of the thread.
*/
public AbstractServerThread(String threadName) {
this.threadName = threadName;
this.setName(getThreadName());
}
/**
* Gets the name of the thread.
* @return the thread name.
*/
public String getThreadName() {
return threadName;
}
}
Code:
/*
An free -- open-source -- RuneScape emulator.
Copyright (C) 2012, Thomas Le Godais <[email protected]>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.thomaslegodais.aura.thread.impl;
import com.thomaslegodais.aura.thread.AbstractServerThread;
/**
* An {@link AbstractServerThread} used for loading context for the server, by
* this I am meaning anything not related the core/networking so things like
* <b>ItemDefinition</b> will be loaded here.
*
* @author Thomas <[email protected]>
*/
public class ContextServerThread extends AbstractServerThread {
/**
* Constructs a new {@code ContextServerThread} instance.
*/
public ContextServerThread() {
super("ContextServerThread");
}
/*
* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
}
}