As I had mentionned a while back, I think that one thing that has been lacking for a long time on this forum are good basic tutorials for our newbie users and wannabe coders, so they can learn the basics of coding for L2J(and in general) and can therefore give back better contributions to the community. Since nothing has been done to encourage(at least nothing that I noticed...) the creation of such tutorials, I'll make the first one right here, right now!
I hope that this small contribution of mine will help you guys(and girls) who are new to server development and put you on your way to become active members of this community.
The tools that you will require:
In order to start working on Java code, you should get one of the great FREE Java IDE available. I would strongly recommend either NetBeans or Eclipse (I use Eclipse myself, but many prefer NetBeans).
And that's about it as far as tools! Follow the installation instructions and make sure you have the latest Java JDK installed!
The basics of Java
Ok, first of all, there is something you NEED to understand if you are to comprehend anything that follows: players, mobs, npcs, skills, items, etc... DO NOT exist as far as Java is concerned!
They are all the same thing, lines of code(and objects)!
It is vital that you understand this if you want to understand anything else. So get out of your "player pants" and into your "programmer pants"
Part 1: The Classes
Dont be fooled by the name, this has nothing to do with "fighter","mage",etc classes
In Java, a class is basically a script file, not unlike the .py files that are used for the quest scripts.
A java program is composed of a number of class files. So basically, a java application(like a L2J server for example), is made of a group of script files which "talk" to each other (yeah, I know.. it's not exactly that but it's a simple way to explain it to those who dont know anything about this)
A simple class could look something like this:
Code: Select all
package javatutorial; public class JavaTutorial{ private static int tutoId = 101; public static int getTutoId() { return tutoId; }}
These terms define the type of variable/method in front of which they are placed.
Example:
Code: Select all
public static List<String> nameList = new ArrayList<String>();
private : The variable/method can only be called from inside its class.
public : The variable/method can be called from any other class that imports its class
static : a variable/method that has the same value no matter in which instance of its class (see "The Objects" further down)
Part 3: The types of variables
There are many types of variables that can be used in Java, but there is something ESSENTIAL for your variables to be useable:
You NEED to define of what type a variable is before you use it.
For those of you who code in PhP or Python, this will be a new habit to develop.
There are a few ways to declare a variable:
Uninitiated: (might throw errors if you forget to give it a value)
Code: Select all
private String name;
Code: Select all
private String name = "";
int : an integer number (no decimals) ranging from -2.147kkk to 2.147kkk
double : this is NOT a double number!!! a double means a decimal number. For example, 3.453 is a double
long : a long integer, which can range from -9223372036854775808 to 9223372036854775807 . It is used for example to get the current time in milliseconds -> System.currentTimeMillis()
String : a letter, a word, a group of words are Strings.
boolean : a true or false value (exemple: private boolean isGM = true; )
Part 4: The Objects
Java is an object-oriented programming (OOP) language. This means that everything is based on objects.
Q:"But what the hell are objects?"
A:Put simply, an object is an instance of a class that is unique. Or even more simple, for each object created, it is linked to a unique "copy" of a class.
Ok, this doesnt sound simple... I know... lets try to explain this a bit better
Lets go back to the L2J code for one minute, and examine the way a monster is created.
THESE ARE NOT REAL L2J FILES, THEY ARE MEANT JUST TO HELP YOU LEARN
Code: Select all
package base; public class L2Object{ private int hp = 100; private int mp = 50; private String name = "monster1"; public int getHp() { return hp; } public int getMp() { return mp; } public String getName() { return name; } public void setHp(int newHp) { hp = newHp; } public void setName(String newName) { name = newName; } public void setMp(int newMp) { mp = newMp; }}
Code: Select all
package base; public class Monster extends L2Object{ private boolean isAggro = false; public boolean isAggro() { return isAggro; } public void setAggro(boolean val) { isAggro = val; }}
Lets see what happens if we "create" a monster.
Code: Select all
Monster mob = new Monster();
We have created a new instance of the Monster class. Instantiation has NOTHING to do with the dungeon instances in L2J, it's a way of saying that we created a new unique copy of the Monster.java class that is linked to our new "mob" variable.
So if after creating it we do this:
Code: Select all
mob.setAggro(true);
I hope you're following so far, because it's about to get a bit more interesting
Lets get back to the "extends L2Object" part that we can see in Monster.java
This tells us that the Monster class is an extention of the L2Object class.
In other words, each time you instantiate the Monster class, you're also instantiating the L2Object class with it.
This means that we can also use the methods contained in L2Object on our mob!
Code: Select all
mob.setHp(4000);
Part 5: Packets... what the hell is that?
Packets are streams of information sent from one application to another, usually in different locations on a network(internet is a network ).
The types of data that can be sent vary from Streams, String, Integers, Doubles, Bytes, etc...
There are 2 main types of connections used: UDP and TCP
Both have their strenghts and weaknesses, but it's not vital to go through this here. You can easily find informations on these if you google them.
If you look in the packets section of the L2J core, you will find a series of files which handle packets for many different purposes.
These are "worker classes" made to handle packets sent/received to/from the client and login server.
Inside these classes you will notice alot of writeS, readI, etc...
These methods are implemented in a superclass of these packet workers and have for function to read the informations contained in the packets received or write informations into a packet sent.
You should study the packet folders in the L2J core extensively, as they are the heart of what makes the L2J server work!
Part 6: Encryption, Encoding
I will not cover detailed explanations here as this is meant to be a basic tutorial. If you desire more in-depth informations you can look it up on the internet.
Encryption: Put simple, this is a process during which information is made unreadable unless you have the correct key to decrypt that information.
Encoding: This is a process which transforms information from one format to another. In many cases, it's used to transform Strings into other strings which do not contain any foreign characters, therefore are portable from one system to another. Note: encryption is also an advanced form of encoding.
Part 7: Threads
Ok, now this is a bit more advanced stuff, but I want to explain the basic idea behind threads and what they do.
Each program has 1 main thread to start with.
This Thread could be compared to a 1-way street.
So if you are calling many different methods, they will be executed somewhat like this:
-> method1 -> method2 -> method3
In most cases, this is more than sufficient, but when you have time-consuming methods or if you need to run many methods at the same time you then need to create new threads. To create a thread, you need to either extend the Thread class with the class you want to use or create a Runnable class like so(this is my prefered method):
Code: Select all
class ThreadableAction implements Runnable{ public void run() { // Your code goes here... }}
Lets see how we create a new thread and what the result will be
Code: Select all
Thread t = new Thread(new ThreadableAction);t.start();
-> ThreadableAction
So now this method will be done separately from the rest of methods on the main thread.
Multi-threading is the way multi-task is handled on our computers.
We use quite alot of multi-threading on L2J servers, especially for packets.
Each time a new packet is received a new thread is created and it is passed to a worker(the class files in the core /network folders)
This allows to handle a great number of packets at the same time. Without doing this, the servers would lag even with only 2 or 3 players because the server would need to wait for 1 packet to be handled completely before going to the next.
[/i]
I hope this helps some of you, if you have anything to add please feel free!