Witaj
Gość

Wątek: [Poradnik] Core - Modyfikacje  (Przeczytany 16759 razy)

  • *******
  • Wiadomości: 1092

  • Pochwał: 22

[Poradnik] Core - Modyfikacje
« dnia: Czerwiec 21, 2009, 04:35:25 pm »
Core - Modyfikacje





W tym temacie będę podawał i opisywał różne modyfikacje core L2J

Temat ten będzie jednocześnie poradnikiem, FAQ i Share dotyczącym Javy

Wszelkie kody będę umieszczał pod macierzysty projekt L2J, jeśli ktoś chce dodać go pod inny, musi go edytować



Czego potrzebujmy :

Eclipse Classic 3.4.2 (152mb) - Pobierz



Jeśli masz zamiar korzystać z tego tematu to obowiązkowo musisz przeczytać ten temat : Eclipse - Kompilacja

Pisze tam także jak przygotować Eclipse do pracy



Wszystkie kody, zanim zostaną umieszczone są przeze mnie testowane! 

Guide by Matim



Kliknij w odnośnik aby przenieść się do danej części tego Tematu :

• Dodawanie Patcha

• Własny Config

• Własna Komenda

• Innowacyjny Enchant

• Nowy Plik Properties

• Własny Item Handler

• Niekończące się Shoty

• Zakaz używania danego Itemu

• Nagroda za PvP lub Pk

• Własny Scroll Of Escape

• Dokumentacja Kodu

• Zmiana Waluty Serwera

• Władny NPC Crafter
« Ostatnia zmiana: Październik 03, 2010, 08:46:03 pm wysłana przez Matim »


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: JAVA - w budowie
« Odpowiedź #1 dnia: Czerwiec 21, 2009, 04:36:05 pm »


Dodawanie Patcha :

• Po pierwsze trzeba ustalić czym jest Patch jest to plik, który zawiera dane na temat różnic między dwiema wersjami tego samego pliku . Owy plik nanosi poprawki lub zmiany . Taka poprawka może występować w następujących formatach :

- plik .diff
- plik .java
- plik .txt

• Jak dodawać Patch do naszego źródła (.txt/.diff) ?

- otwieramy Eclipse i przechodzimy do zakładki z naszym Projektem (Project Explorer)
- jeśli nie mamy tej zakładki to klikamy : Window -> Show View -> Project Explorer
- w nowym okienku będziemy widzieli nasz WorkSpace
- klikamy prawym przyciskiem myszy na folder z Source, klikamy Team a następnie Aplly Patch



- następnie wskazujemy miejsce, w którym znajduje się nasz patch i dajemy Finish

• Często jednak zdarza się, że patch nie pasuje do naszego źródła, można wtedy albo szukać przyczyny błędu albo dodać patch ręcznie . Jak odczytać zmiany ?

- oto przykładowy patch (wycinek) :

Index: C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java (revision 3148)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java (working copy)
@@ -507,8 +507,21 @@
- public static boolean CUSTOM_TELEPORT_TABLE;
- public static boolean CUSTOM_DROPLIST_TABLE;
- public static boolean CUSTOM_MERCHANT_TABLES;

+ public static boolean CHARTITLESTART;
+ public static String CHARTITLE;

- a oto wyjaśnienie :

Index: C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java
Ścieżka i plik, który ma być zmodyfikowany

(revision 3148)
Revision (wersja), na która został utworzony

@@ -507,8 +507,21 @@
Linijki do edycji

- public static boolean CUSTOM_TELEPORT_TABLE;
- public static boolean CUSTOM_DROPLIST_TABLE;
- public static boolean CUSTOM_MERCHANT_TABLES;

Minus oznacza, że te linijki mają zostać usunięte

+ public static boolean CHARTITLESTART;
+ public static String CHARTITLE;

Plus oznacza, że te linijki mają zostać dodane
« Ostatnia zmiana: Lipiec 06, 2009, 11:39:12 am wysłana przez Matim »


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: JAVA - w budowie
« Odpowiedź #2 dnia: Lipiec 06, 2009, 11:40:16 am »
Własny Config :

• Zastanawiasz się jak zrobić swój własny plik konfiguracyjny ? (gameserwer/config/xxx.properties) Oto przykład :

- Dla przykładu, chce stworzyć config, który będzie zezwalał lub nie na nadawanie automatycznie 75 lvl każdej nowo stworzonej postaci, a więc :
- Otwórz plik Config.java (java\net\sf\l2j)
- Chcemy zrobić plik konfiguracyjny z dwiema możliwościami (true lub false), a więc musimy zarejestrować public "static boolean
- otworzyliśmy plik Config.java i idziemy do linijki,w której zaczyna się Klasa "Config" Zaczyna się tak :

public final class Config
{

         protected static final Logger _log = Logger.getLogger(Config.class.getName());
 ...itd

- Rejestrujemy nasz config, dopiszmy go na początku, a więc ma to wyglądać tak :

Cytuj
public final class Config
{
    /** Custom Starting Level*/
    public static boolean ALLOW_CREATE_LVL;

   
    protected static final Logger _log = Logger.getLogger(Config.class.getName());

    ...itd

- Ok to już dodaliśmy, teraz trzeba nasz config zarejestrować do któregoś pliku konfiguracyjnego, na początek dodamy do już jakiegoś gotowego . Niech będzie other.properties
- Jesteśmy dalej w pliku Config.java, tym razem odszukaj tych linijek :

            // other
            try
            {
                Properties otherSettings    = new Properties();
                InputStream is              = new FileInputStream(new File(OTHER_CONFIG_FILE));
                otherSettings.load(is);
                is.close();

                DEEPBLUE_DROP_RULES=Boolean.parseBoolean(otherSettings.getProperty("UseDeepBlueDropRules","True"));                                                                                   

 ...itd

- U mnie zaczynają się na linijce 1451, ale ja aktualnie bawię się na starszych plikach L2J - Interlude
- w tym pliku jak już mówiłem dodajemy configi do ... pliku konfiguracyjnego - w tym przypadku other.properties
- nasz config dodajemy na początku czyli nad :

DEEPBLUE_DROP_RULES=Boolean.parseBoolean(otherSettings.getProperty("UseDeepBlueDropRules","True"));
- Ma to wyglądać tak :

Cytuj
            // other
            try
            {
                Properties otherSettings    = new Properties();
                InputStream is              = new FileInputStream(new File(OTHER_CONFIG_FILE));
                otherSettings.load(is);
                is.close();
            
            ALLOW_CREATE_LVL = Boolean.parseBoolean(otherSettings.getProperty("CostumStartLvl", "False"));

                DEEPBLUE_DROP_RULES = Boolean.parseBoolean(otherSettings.getProperty("UseDeepBlueDropRules", "True"));

           ... itd

- Tłumaczyć co do czego i jak działa nie będę, wszystko można logicznie wywnioskować . Dodatkowo przeglądając plik Config.java szybko domyślicie się jak zrobić osobny plik konfiguracyjny ( np. matim.properties )
- Ok, a więc rejestracje naszego configa zakończyliśmy !

- Kolejnym krokiem jest zdefiniowanie naszego configa, ma on dawać doświadczenie dla nowych postaci, a więc odszukaj plik : CharacterCreate.java
- Odszukać należy te linijki :

// cSdddddddddddd
private String _name;
    private int _race;
private byte _sex;
private int _classId;
private int _int;
private int _str;
private int _con;
private int _men;
private int _dex;
private int _wit;
private byte _hairStyle;
private byte _hairColor;
private byte _face;

i dodać nowy wpis mówiący o doświadczeniu :

private long _exp;
- teraz należy zdefiniować "_exp" w tym przypadku jego ilość
- szukamy takich linijek :

@Override
protected void readImpl()
{
_name      = readS();
_race      = readD();
_sex       = (byte)readD();
_classId   = readD();
_int       = readD();
_str       = readD();
_con       = readD();
_men       = readD();
_dex       = readD();
_wit       = readD();
_hairStyle = (byte)readD();
_hairColor = (byte)readD();
_face      = (byte)readD();

i dodajemy :

_exp    = 804219972;
}

- (804219972;) = ilość doświadczenia potrzebna na 75 lvl, jeśli chcesz inny poziom to zwyczajnie wpisz inną ilość doświadczenia .

- Teraz szukamy jednie tej linijki :

newChar.setXYZInvisible(template.spawnX, template.spawnY, template.spawnZ);
i pod nią dodajemy taki wpis :

if(Config.ALLOW_CREATE_LVL)
{
newChar.removeExpAndSp(newChar.getExp(), 0);
newChar.addExpAndSp(_exp, 0);
}

- Tego wpisu tłumaczyć chyba też nie trzeba . Sprawdza on po prostu czy config zezwala na "customowy poziom startowy" i jeśli tak to każdej nowej postaci automatycznie dodaje tyle doświadczenia ile zdefiniowaliśmy w ( _exp; )

- Proste, prawda :) ?

- Ostatni krok do dodanie wpisu do pliku konfiguracyjnego other.properties

- Otwieramy go i na początku dodajemy :

# Zezwalaj na custom początkowy poziom nowych postaci, docelowo = false
# Gdy wpiszesz True , każda nowa postać otrzyma automatycznie 75 poziom
CostumStartLvl = False

- No i gdy chcemy aby każda nowa postać otrzymywała automatycznie 75 poziom dajemy True

- Kompilujemy Serwer i gotowe, cieszymy się własnym configiem  :D


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: JAVA - w budowie
« Odpowiedź #3 dnia: Lipiec 06, 2009, 11:40:54 am »
Własna Komenda :

• Tworzenie nowych Komend można podzielić na dwa rodzaje :

- legalne ( .komenda ) - bez modyfikowania Clienta
- nielegalne ( /komenda ) - trzeba modyfikować Clienta

Teraz opisze jak stworzyć legalną komendę, jeśli wolisz tą pierwszą to opisałem przebieg jej tworzenia TUTAJ

• Ok, a więc zaczynamy . Powiedzmy, że chcemy przygotować komendę, która będzie zawiera opis dotacji (np .donate)

- Pierwszym krokiem jest przygotowanie kody komendy . Posłużymy się zlepkiem z innych komend
- Otwórz folder : java\net\sf\l2j\gameserver\handler\voicedcommandhandlers
- Tworzymy tam nowy plik Javy . Na przykład : Donate.java
- umieszczamy tam taki kod :

/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU 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 General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see http://www.gnu.org/licenses/
 */
package net.sf.l2j.gameserver.handler.voicedcommandhandlers;

import net.sf.l2j.Config;
import net.sf.l2j.gameserver.GameServer;
import net.sf.l2j.gameserver.cache.HtmCache;
import net.sf.l2j.gameserver.handler.IVoicedCommandHandler;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.serverpackets.NpcHtmlMessage;

public class VoiceInfo implements IVoicedCommandHandler
{
private static String[] VOICED_COMMANDS =
{ "donate" };

/* (non-Javadoc)
* @see net.sf.l2j.gameserver.handler.IVoicedCommandHandler#useVoicedCommand(java.lang.String, net.sf.l2j.gameserver.model.actor.instance.L2PcInstance, java.lang.String)
*/
public boolean useVoicedCommand(String command, L2PcInstance activeChar, String target)
{
String htmFile = "data/html/custom/donate.htm";
String htmContent = HtmCache.getInstance().getHtm(htmFile);
if (htmContent != null)
{
NpcHtmlMessage infoHtml = new NpcHtmlMessage(1);
infoHtml.setHtml(htmContent);
activeChar.sendPacket(infoHtml);
}
else
{
activeChar.sendMessage("Przepraszamy,ale   " + htmFile + " ! jest tymczasowo niedostępny!");
}
return true;
}

public String[] getVoicedCommandList()
{
return VOICED_COMMANDS;
}
}

- i tłumacze co i jak :

{ "donate" };
Jest to nazwa komendy (czyli w grze gdy wpiszemy .donate to wypełni się jego funkcja )

String htmFile = "data/html/custom/donate.htm";
Tutaj podajemy ścieżka do pliku .htm, który ma zostać wyświetlony po wpisaniu tej komendy

}
else
{
activeChar.sendMessage("Przepraszamy, ale   " + htmFile + " ! jest tymczasowo niedostępny!");
}
return true;

Ten kod sprawdzi czy plik donate.htm jest tam gdzie powinien, jeśli nie to wyświetli komunikat o tym, że plik jest tymczasowo niedostępny (oczywiście zmieniamy to wg własnego życzenia) [" + htmFile + "] oznacza pobranie nazwy pliku htm i wstawienie tej nazwy do komunikatu.

- Teraz pozostaje nam jedynie zarejestrować komendę. W tym celu do folderu java\net\sf\l2j\gameserver\handler\ i otwórz plik VoiceCommandHandlers.java

- Do listy importów na początku pliku dodajemy import naszej komendy :

import net.sf.l2j.gameserver.handler.voicedcommandhandlers.Donate;
- Następnie w :

private VoicedCommandHandler()
{

dodajemy naszą komendę :

registerVoicedCommandHandler(new Donate());
• Zapisujemy, kompilujemy i gotowe !


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: JAVA - w budowie
« Odpowiedź #4 dnia: Lipiec 06, 2009, 11:41:54 am »
Innowacyjny Enchant :

• Docelowo udany enchant daje nam +1 do poziomu ulepszenia broni . Jak to zmienić ?

- Otwieramy ten folder : \java\net\sf\l2j\gameserver\clientpackets

- Szukamy takiego pliku : RequestEnchantItem.java

- Odszukaj w nim takie linijki :

            else
            {
            sm = new SystemMessage(SystemMessageId.S1_S2_SUCCESSFULLY_ENCHANTED);
            sm.addNumber(item.getEnchantLevel());
            sm.addItemName(item.getItemId());
            activeChar.sendPacket(sm);
            }
            item.setEnchantLevel(item.getEnchantLevel()+1);
            item.updateDatabase();
            }
        }

- A teraz zmieniamy tą wartość na taką jaka nas interesuje :

Cytuj
item.setEnchantLevel(item.getEnchantLevel()+1);

- Dla przykładu gdy wpiszemy +5 to po udanym enchantowaniu naszej broni dostaniemy automatycznie +5 do poziomu ulepszenia broni . Przydatne na Serwery Custom Hight Rate's



• (byVeandil) -  Po enchantowaniu przedmiotów blessed scroll'ami przedmiot spada do 0, jest jednak możliwa zmiana aby tak się nie dzialo.

- Otwieramy ten folder : \java\net\sf\l2j\gameserver\clientpackets

- Szukamy takiego pliku : RequestEnchantItem.java

- Odszukaj w nim takie linijki :

if (scrollTemplate.isBlessed())
{
// blessed enchant - clear enchant value
sm = new SystemMessage(SystemMessageId.BLESSED_ENCHANT_FAILED);
activeChar.sendPacket(sm);

item.setEnchantLevel(0);
item.updateDatabase();
activeChar.sendPacket(new EnchantResult(3, 0, 0));
a teraz zmieniamy wartość na tę która nas interesuje (proponuje tu użyć wartości safe enchantu)

item.setEnchantLevel(0);
« Ostatnia zmiana: Grudzień 17, 2009, 09:38:19 pm wysłana przez Matim »


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: JAVA - w budowie
« Odpowiedź #5 dnia: Lipiec 06, 2009, 11:42:23 am »
Nowy Plik Properties :

• Dobrze, a więc jednak omówię jak przygotować swój własny plik .properties (config) np matim.properties. Zawsze to lepiej trzymać nowe configi w osobnym pliku niż dodawać do już istniejących, ale oczywiście jak kto woli.

1. Otwórz plik Config.java, który znajduje się w folderze : \java\net\sf\l2j

2. Na początku zarejestrujemy nasz nowy plik .

3. Szukamy linijek, które zaczynają się od :

//--------------------------------------------------
// L2J Property File Definitions
//--------------------------------------------------
public static final String CHARACTER_CONFIG_FILE = "./config/Character.properties";

4. Teraz pod ostatnią linijką z tego "działu" dodamy nasz config (zarejestrujemy)

5. Jak to zrobić ? Na przykładzie tego jak zrobiono inne, a więc dodajemy :

Cytuj
public static final String NAZWA_CONFIG_FILE = "./config/NAZWA.properties";

6. W miejscach, które wyróżniłem podajemy nazwę naszego configa, a tutaj przykład jak może to wyglądać :

Cytuj
public static final String MATIM_CONFIG_FILE = "./config/matim.properties";

7. Tym sposobem zarejestrowałeś swój własny, unikalny plik konfiguracyjny .properties!

8. Teraz utworzymy miejsce na nasze configi . Jak to zrobić ?

9. Przechodzimy do linijek, w których definiujemy które configi należą do danego pliku. Zaczyna się to od :

Cytuj
/**
    * This class initializes all global variables for configuration.<br>
    * If the key doesn't appear in properties file, a default value is set by this class.
    * @see CONFIGURATION_FILE (properties file) for configuring your server.
    */
   public static void load()
   {
      if(Server.serverMode == Server.MODE_GAMESERVER)
      {
         _log.info("Loading GameServer Configuration Files...");
         InputStream is = null;
         try
         {
            try
            {
...itd

10. Teraz pod jakimś configiem dodamy nasz. Na przykład na linijce 955 nad która znajduje się :

Cytuj
........

                  throw new Error("MinProtocolRevision is bigger than MaxProtocolRevision in server configuration file.");
               }
            }
            catch (Exception e)
            {
               e.printStackTrace();
               throw new Error("Failed to Load "+CONFIGURATION_FILE+" File.");
            }

11. I na zasadzie podchwytywania jak coś zostało zrobione piszemy na np linijce 955 (pamiętaj, że to przykład - dodaj swojego configa na której chcesz linijce, ale w miejscu do tego przeznaczonym w w/w miejscu.)

Cytuj
// Load matim Properties file (if exists)
            try
            {
               Properties matimSettings = new Properties();
               is = new FileInputStream(new File(MATIM_CONFIG_FILE));
               matimSettings.load(is);

                   
                                 //Tutaj dodajemy Lokacje Configa . Np :
                                CHAR_TITLE = Boolean.parseBoolean(matimSettings.getProperty("CharTitle", "false"));
         
    
               
            }
            catch (Exception e)
            {
               e.printStackTrace();
               throw new Error("Failed to Load "+PVP_CONFIG_FILE+" File.");
            }

12. "matim" zastępujemy nazwą naszego configa, którego wcześniej rejestrowaliśmy. Przykładowy config (na custom starting level" podałem trochę wyżej, a więc jeśli ktoś czyta skrupulatnie to na pewno zrozumie.

• Teraz jedynie tworzymy nowy plik .properties w folderze Config, dodajemy nasze configi - kompilujemy i gotowe!


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: Core - Modyfikacje
« Odpowiedź #6 dnia: Lipiec 08, 2009, 11:44:01 am »
Własny Item Handler :

• Na wstępie odpowiedzmy sobie co to jest. Jest to przedmiot, który wykonuje jakąś akcje (np po naciśnięciu) czyli np Soul Shoty, początkowa książka z tutorialem, potion itp.

• Zacznijmy od najprostszego. Czyli nowego itemka, który będzie wyświetlał nam plik .htm Posłużymy się kodem jaki został zastosowany do Tutorial Guide (itemek, która każda nowa postać dostaje na start) Jak wiemy wyświetla on plik .htm

1. Pierwszy krok to udanie się do folderu : gameserver/handler/itemhandlers i stworzenie nowego pliku .java Np Matim.java

2. Otwieramy nasz nowo utworzony plik i wklejamy kod, który jest używany do w/w książki :

ackage com.l2jfree.gameserver.handler.itemhandlers;

import com.l2jfree.Config;
import com.l2jfree.gameserver.handler.IItemHandler;
import com.l2jfree.gameserver.GameServer;
import com.l2jfree.gameserver.cache.HtmCache;
import com.l2jfree.gameserver.model.actor.instance.L2PcInstance;
import com.l2jfree.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jfree.gameserver.handler.IItemHandler;
import com.l2jfree.gameserver.model.L2ItemInstance;
import com.l2jfree.gameserver.model.actor.instance.L2PcInstance;
import com.l2jfree.gameserver.model.actor.instance.L2PlayableInstance;

public class Matim implements IItemHandler
{
private static final int[] ITEM_IDS = { ID_Przedmiotu! };

public void useItem(L2PlayableInstance playable, L2ItemInstance item)
    {
      if (!(playable instanceof L2PcInstance))
         return;
      L2PcInstance activeChar = (L2PcInstance)playable;
       int itemId = item.getItemId();
     
   if (itemId == ID_Przedmiotu)
       {
String htmFile = "data/html/Custom/Matim.htm";
String htmContent = HtmCache.getInstance().getHtm(htmFile);

NpcHtmlMessage infoHtml = new NpcHtmlMessage(1);
infoHtml.setHtml(htmContent);
activeChar.sendPacket(infoHtml);
       }
    }

    public int[] getItemIds()
    {
    return ITEM_IDS;
    }
}   

• I tłumacze co i jak:

Cytuj
public class Matim implements IItemHandler

- Jest to nasza nowa klasa odnosząca się do IItemHandler'sów - nazywamy ją tak samo jak nasz plik (w tym przypadku Matim)

Cytuj
private static final int[] ITEM_IDS = { ID_Przedmiotu! };

- Tym kodem definiujemy ID przedmiotu jaki będzie wykonywał akcje, która zdefiniujemy niżej. W "ID_Przedmiotu" wpisujemy ID naszego itemka, który ma wykonać akcje po naciśnięciu (np 123456)

Cytuj
if (itemId == ID_Przedmiotu)

- Tutaj stosujemy instrukcję warunkową if. Co ona robi? Sprawdza czy ID przedmiotu, który klikneliśmy jest tym, który zdefiniowaliśmy. Podajemy tam znowu ID itemku, który ma wywoływać akcje. Jeśli ID itemka jest tym, który zdefiniowaliśmy/podaliśmy to zwraca true i wykonuje akcje.

• Ważniejsze części kodu objaśnione, a więc teraz zapisujemy nasz plik i idziemy dalej.

3. Otwieramy folder gameserver/handler a w nim plik:  ItemHandler.java

4. Pozostaje nam jedynie zarejestrowanie naszego itemka :

Cytuj
registerItemHandler(new Matim());

5. Kompilujemy i gotowe.


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: Core - Modyfikacje
« Odpowiedź #7 dnia: Lipiec 08, 2009, 12:01:56 pm »
Niekończące się Shoty

• Co zrobić aby nasza postać nie musiała dźwigać tysięcy SoulShotów i blessedSpiritShotów? Co zrobić aby każdej postaci wystarczyło jedynie jedna sztuka tego przedmiotu?

• Odpowiedź jest prosta jak drut - usunąć część kodu, która odpowiada za pobieranie następnego np SoulShota.

1. Na początku zajmiemy się Soul'Shotami. Otwieramy folder: gameserver/handler/itemhandlers i plik: SoulShots.java

2. Na wstępie należy usunąć dwa zbędne importy (w tym przypadku!)

3. Odszukaj i usuń te importy :

Cytuj
import net.sf.l2j.gameserver.network.serverpackets.ExAutoSoulShot;
import net.sf.l2j.gameserver.skills.Stats;

4. Teraz jedynie usuniemy kilka linijek kodu. Odszukaj i usuń te linijki:

// Consume Soul shots if player has enough of them
int saSSCount = (int) activeChar.getStat().calcStat(Stats.SOULSHOT_COUNT, 0, null, null);
int SSCount = saSSCount == 0 ? weaponItem.getSoulShotCount() : saSSCount;

if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), SSCount, null, false))
{
if (activeChar.getAutoSoulShot().containsKey(itemId))
{
activeChar.removeAutoSoulShot(itemId);
activeChar.sendPacket(new ExAutoSoulShot(itemId, 0));

SystemMessage sm = new SystemMessage(SystemMessageId.AUTO_USE_OF_S1_CANCELLED);
sm.addString(item.getItem().getName());
activeChar.sendPacket(sm);
}
else
activeChar.sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_SOULSHOTS));
return;
}

• Ta część kodu odpowiadała za sprawdzanie ilości Soul'Shotów i pobieranie kolejno następnego jeśli ilość była większa niż 0. Usunęliśmy ten kod, a więc teraz wystarczy posiadać jednego Soul'Shota!

5. Zapisujemy i kompilujemy.



• Teraz zajmiemy się blessedSpirit'Shotami, sytuacja jest praktycznie taka sama.

1. Otwieramy plik: BlessedSpiritShot.java

2. Odszukaj i usuń ten import:

Cytuj
import net.sf.l2j.gameserver.network.serverpackets.ExAutoSoulShot;

3. Teraz odszukaj i usuń te linijki

// Consume Blessed SpiritShot if player has enough of them
if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), weaponItem.getSpiritShotCount(), null, false))
{
if (activeChar.getAutoSoulShot().containsKey(itemId))
{
activeChar.removeAutoSoulShot(itemId);
activeChar.sendPacket(new ExAutoSoulShot(itemId, 0));

SystemMessage sm = new SystemMessage(SystemMessageId.AUTO_USE_OF_S1_CANCELLED);
sm.addString(item.getItem().getName());
activeChar.sendPacket(sm);
}
else
activeChar.sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_SPIRITSHOTS));
return;
}
:

4. Zapisujesz, kompilujesz i cieszysz się nie limitowanymi BlessedSpirit'Shotami!

• Te same rzeczy możesz robić z innymi przedmiotami np SS dla petów lub np strzały(tu sytuacja jest trochę inna)


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: Core - Modyfikacje
« Odpowiedź #8 dnia: Lipiec 29, 2009, 11:04:47 am »
Zakaz używania danego Itemu

• Co zrobić aby dana klasa nie mogła zakładać danego itemu? To proste, wprowadzić restrykcje w jego użyciu przez daną klasę. Można to zrobić krótkim kodem.

1. Otwieramy plik UseItem.java (\java\net\sf\l2j\gameserver\network\clientpackets\UseItem.java)

2. Szukamy tych linijek:

if (item.isEquipable())
      {
         if (activeChar.isDisarmed())
            return;

         if (!((L2Equip) item.getItem()).allowEquip(activeChar))
         {
            activeChar.sendPacket(new SystemMessage(SystemMessageId.NO_CONDITION_TO_EQUIP));
            return;
         }
}

3. Pod nimi dodajemy taki kod:

         if (activeChar.getClassId().getId() == 88)
         {
            if (item.getItemType() == L2ArmorType.MAGIC)
            {
               activeChar.sendPacket(new +SystemMessage(SystemMessageId.NO_CONDITION_TO_EQUIP));
               return;
            }   
         }

• Teraz objaśnienie co ten kod robi:

Cytuj
if (activeChar.getClassId().getId() == 88)

- Sprawdza klasę postaci. W tym przypadku jest to 88 czyli Duelist

Cytuj
if (item.getItemType() == L2ArmorType.MAGIC)

- Jeżeli postać (w tym przypadku Duelist) założy armor o typie Magic (czyli Robe) wykona czynność:

Cytuj
activeChar.sendPacket(new +SystemMessage(SystemMessageId.NO_CONDITION_TO_EQUIP))

- Czyli wyśle wiadomość systemową, że nie może założyć tego itemu

- W ten sposób dana klasa nie może zakładać armorów danego typu.
return;

• Równie dobrze możemy zrobić coś takiego dla broni używając:

if (item.getItemType() == L2WeaponType.BOW) - luk

if (item.getItemType() == L2WeaponType.DAGGER) - sztylet

if (item.getItemType() == L2WeaponType.SWORD) - miecz

itp.

• Taki sposób może bardzo pomóc w odpowiednim zbalansowaniu klas.


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: Core - Modyfikacje
« Odpowiedź #9 dnia: Lipiec 29, 2009, 11:22:41 am »
Nagroda za PvP lub Pk

• Jeśli chcesz wprowadzić nagrody za PvP lub Pk musisz dodać kilka linijek prostego kodu do pliku L2PcInstance.java

1. Otwieramy plik PcInstance.java (\java\net\sf\l2j\gameserver\model\actor\instance\PcInstance.java)

• Na wstępie wykonajmy nagrodę za PvP:

2. Szukamy tych linijek:

        // Add karma to attacker and increase its PK counter
        setPvpKills(getPvpKills() + 1);

3. Pod nimi dodajemy taki kod:

addItem("Loot", 57, 1000, this, true);
sendMessage("Wygrałeś 1000 adeny za PvPl!");

• Teraz objaśnienie co ten kod robi:

- Nasz kod znajdzie się w zasięgu:

    public void increasePvpKills()
    {

- Czyli jeżeli ktoś nabije 1 PvP wykona się kod, który dodaliśmy.

Cytuj
addItem("Loot", 57, 1000, this, true);

- Otrzymanie itemu. (57 - item ID, w tym przypadku Adena, 1000 - ilość)

Cytuj
sendMessage("Wygrałeś 1000 adeny za PvPl!");

- Wysyła wiadomość gratulacyjną dla gracza.

• To samo można zrobić dla Pk, teraz należałoby dodać taki kod pod tymi linijkami:

        // Add karma to attacker and increase its PK counter
        setPkKills(getPkKills() + 1);
        setKarma(getKarma() + newKarma);


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: Core - Modyfikacje
« Odpowiedź #10 dnia: Sierpień 07, 2009, 04:55:23 pm »
Własny Scroll Of Escape

• Szybki poradnik na temat "Jak stworzyć własny Scroll Of Escape". Do czego może się nam on przydać? Na przykład na serwerach high rate do jakichś customowych lokacji (pvp zone/farm itp)

1. Otwieramy plik ScrollOfEscape.java (net.sf.l2j.gameserver.handler.itemhandlers) - lub jeżeli używamy nowszych wersji L2J to ten plik znajdziemy w DataPacku (data/scripts/handlers/itemhandlers)

2. Szukamy tych linijek:

    private static final int[] ITEM_IDS = { 736, 1830, 1829, 1538, 3958, 5858, 5859,
      7117,7118,7119,7120,7121,7122,7123,7124,
      7125,7126,7127,7128,7129,7130,7131,7132,
      7133,7134,7135,7554,7555,7556,7557,7558,
      7559,7618,7619};

3. W tych linijkach podajemy ID przedmiotów, które pełnią funkcje SOE. Dodajemy nowe ID naszego przedmiotu (np 1234) Ma to wyglądać tak:

Cytuj
    private static final int[] ITEM_IDS = { 736, 1830, 1829, 1538, 3958, 5858, 5859,
                              7117,7118,7119,7120,7121,7122,7123,7124,
                              7125,7126,7127,7128,7129,7130,7131,7132,
                              7133,7134,7135,7554,7555,7556,7557,7558,
                              7559,7618,7619,1234};

4. Następnie odszukaj tego:

                case 7619 :
                _activeChar.teleToLocation(108275,-53785,-2524, true);  // Varka Silenos Village
                break;

- Tutaj po prostu podajemy gdzie dane SOE ma nas przenosić (x/y/z) Pod tymi linijkami dodaj nowy wpis dla naszego Soe:

Cytuj
                        case 1234 :
                            _activeChar.teleToLocation(X,Y,Z, true);
                            break;

• To wszystko, skompiluj swój serwer i gotowe.

- Ps. To Guide tworzyłem i testowałem na plikach Interlude gdzie handlersy są w core, a nie w DataPacku!


  • *******
  • Wiadomości: 1092

  • Pochwał: 22

Odp: Core - Modyfikacje
« Odpowiedź #11 dnia: Wrzesień 02, 2009, 03:13:31 pm »
Dokumentacja Kodu

• Tym razem napiszę małe guide o dokumentacji kodu. Po pierwsze powinniśmy sobie odpowiedzieć na pytanie, dla czego powinniśmy dokumentować kod, który piszemy. Ano dlatego, że dobrze udokumentowany (i komentowany) kod jest przejrzysty, czytelny i łatwy w zrozumieniu dla osób trzecich. Dodatkowo plik wynikowy przy użyciu narzędzia javadoc będzie bardziej czytelny.

• Na początku zapoznajmy się z komentarzami. Wyróżniamy dwa typy komentarzy.

1. Rozciągający się tylko na jeden wiersz, np:

Cytuj
// Custom Starting Level

2. Rozciągający się na wiele wierszy, np:

Cytuj
/** Custom
   * Starting
   * Level
   */

• Teraz warto wspomnieć o narzędziu javadoc. Rezultatem działania tego programu (który przegląda dany plik javy) jest plik w formacie HTML, odrzuca on komentarze i przedstawia je w pliku html.

• Aby w pliku wynikowym dodać html należy dodać go w komentarzach w pliku javy, np tak:

/**
 * <ol>
 * <li>Something
 * <li>Again
 * <li>Once Again
 * </ol>
 */

• Teraz wspomnimy i znacznikach dokumentacyjnych:

@version - informacje o wersji
@author - informacje o autorze (nik lub np email)
@param - opis danego parametru

Większość już pewnie spotkała się z czymś takim, np na początku kodu, informacja o autorze często wygląda np tak:

/**
 *
 * @author Matim
 *
 */
« Ostatnia zmiana: Wrzesień 02, 2009, 03:15:34 pm wysłana przez Matim »


  • Wiadomości: 50

  • Pochwał: 5

    • kompania obrony wybrzeża ASG
Odp: Core - Modyfikacje
« Odpowiedź #12 dnia: Styczeń 01, 2010, 11:50:14 pm »
Matim wiem, że modyfikacje core to twoja działka tutaj ale też się chce podzielić czymś z ludźmi :P

Zmiana Waluty Serwera

  • zapewne wielu właścicieli jak i graczy serwerów pvp irytuje brak opcji wystawiana przedmiotów na sprzedaż za pomocą waluty serwera(coiny, ancient adena, festival adena itp) aby to umożliwić odszukujemy pliku PcInventory.java(dla l2j ct2.3 w net.sf.l2j.gameserver.model)


  • szukamy tam linijek
    public static final int ADENA_ID = 57;
    public static final int ANCIENT_ADENA_ID = 5575;
    public static final long MAX_ADENA = 99900000000L;
ifor (L2ItemInstance item : _items)
{
if ((!allowAdena && item.getItemId() == 57))
continue;
if ((!allowAncientAdena && item.getItemId() == 5575))
continue;
    (linijki zaznaczone w drugim okienku code występują 2 razy)
    • zmieniamy w tym miejscu wartość ADENA_ID = 57 i if ((!allowAdena && item.getItemId() == 57))  na interesujące nas id
    • UWAGA w inventory nadal jest pokazywana liczba adeny a nie naszej waluty! trzeba także zwrócić uwagę na fakt że przedmioty będą sprzedawane w sklepie za naszą walutę. może to spowodować fakt że różnica między sprzedażą a kupnem wyjdzie na plus dla graczy i za darmo w ten sposób będą zbierać ogromne ilości kasy. aby tego uniknąć polecam użyć zapytania do SQL w postaci
update `weapon` set `price` = 0; update `etcitem` set `price` = 0; update `armor` set `price` = 0 co spowoduje że przedmioty do sklepu będą oddawane za darmo



/Matim - Plusik.


« Ostatnia zmiana: Styczeń 02, 2010, 10:22:58 am wysłana przez Matim »
WWW.KOMPANIA-OW.XORG.PL
ASG to nie tylko zabawa- to sposób życia


  • Wiadomości: 15

  • Pochwał: 1

Odp: Core - Modyfikacje
« Odpowiedź #13 dnia: Luty 23, 2010, 01:41:14 pm »
Npc Crafter
Postanowiłem napisać jak zrobić Npc Craftera do serwera L2J Gracia Final

1. Idziemy do:
java/net/sf/l2j/gameserver/model/actor/instance/I tworzymy nowy plik:
L2CraftManagerInstance.java2. Wklejamy do niego:
L2CraftManagerInstance.java

Trochę objaśnień:
public static final int ADENA_ID = 57;W tej linijce jest ID przedmiotu za które Craft Manager będzie krafcił nam itemki. W tym przypadku jest to ID 57 czyli Adena
public static final int ITEMS_PER_PAGE = 5;Zaś ta linijka mówi nam ile itemków będzie wyświetlanych na 1 stronie. W tym przypadku jest to 5
return "data/html/NPCCRAFTER/" + pom + ".htm";Ta linijka mówi nam gdzie ma być wstawiony plik HTM naszego Craft Managera

Tutaj podaję link do pliku w którym są podane wszystkie ID itemków z Lineage ][ Klik
3. Teraz trzeba dodać nowe configi. W tym celu idziemy do:
java/net/sf/l2j/Config.javai szukamy takich linijek:
public static int OFFLINE_NAME_COLOR;
public static boolean L2JMOD_ENABLE_MANA_POTIONS_SUPPORT;
U mnie są to "617" i "618"
pod nimi dodajemy takie coś:
public static int       CRAFT_MANAGER_PRICE_MULTIPLIER;
public static int       CRAFT_MANAGER_DEFAULT_PRICE;
public static boolean   CRAFT_MANAGER_DWARVEN_CRAFT;
public static boolean   CRAFT_MANAGER_COMMON_CRAFT;
public static boolean   CRAFT_MANAGER_CRYSTALLIZE;
public static int       CRAFT_MANAGER_PRICE;
Potem szukamy:
BANKING_SYSTEM_ENABLED = Boolean.parseBoolean(L2JModSettings.getProperty("BankingEnabled", "false"));
BANKING_SYSTEM_GOLDBARS = Integer.parseInt(L2JModSettings.getProperty("BankingGoldbarCount", "1"));
I nad nimi dodajemy:
CRAFT_MANAGER_PRICE_MULTIPLIER = Integer.parseInt(L2JModSettings.getProperty("CraftManagerPriceMultiplier", "1"));
CRAFT_MANAGER_DEFAULT_PRICE = Integer.parseInt(L2JModSettings.getProperty("CraftManagerDefaultPrice", "50000"));
CRAFT_MANAGER_DWARVEN_CRAFT = Boolean.parseBoolean(L2JModSettings.getProperty("CraftManagerDwarvenCraft", "True"));
CRAFT_MANAGER_COMMON_CRAFT = Boolean.parseBoolean(L2JModSettings.getProperty("CraftManagerCommonCraft", "True"));
CRAFT_MANAGER_CRYSTALLIZE = Boolean.parseBoolean(L2JModSettings.getProperty("CraftManagerCrystallize", "True"));
CRAFT_MANAGER_PRICE = Integer.parseInt(L2JModSettings.getProperty("CraftManagerPrice", "2"));
4. Teraz idziemy do:
java/config/l2jmods.propertiesI na samym dole dodajemy:
# ---------------------------------------------------------------------------
# Npc Crafter
# ---------------------------------------------------------------------------
# Czy Craft Manager może krafcić zwykłe itemy ?
# Domyślnie: True
CraftManagerDwarvenCraft = True
# Czy Craft Manager może krafcić common itemy ?
# Domyślnie: True
CraftManagerCommonCraft = True
# Czy Craft Manager może krystalizować itemy ?
# Domyślnie: True
CraftManagerCrystallize = True
# Tutaj podaj ile razy więcej Craft Manager bedzię brał rzeczy za 1 craft
# Np. na recipe AM trzeba 200 DMP jeżeli tutaj bedzie podane 2 to trzeba bedzię 2 razy więcej czyli 400 DMP
# Domyślnie: 1
CraftManagerPriceMultiplier = 1
# Domyślna cena u Craft Managera
# Domyślnie: 50000
CraftManagerDefaultPrice = 50000
# Nie ustawiaj tej opcji za wysokiej bo Craft Manager będzie za drogi !
# Domyślnie: 2
CraftManagerPrice = 2

5. Teraz idziemy do:
java/net/sf/l2j/gameserver/model/Otwieramy plik L2Multisell.java i na samym dole mamy
   @SuppressWarnings("synthetic-access")
   private static class SingletonHolder
   {
      protected static final L2Multisell _instance = new L2Multisell();
   }
}
Dodajemy tam takie coś:
public void separateAndSend(int parseInt, L2PcInstance player, boolean b,
double taxRate) {}}
Całość ma wyglądać tak:
   @SuppressWarnings("synthetic-access")
   private static class SingletonHolder
   {
      protected static final L2Multisell _instance = new L2Multisell();
   }

public void separateAndSend(int parseInt, L2PcInstance player, boolean b,
double taxRate) {}}
Po dodaniu można skompilować już GAMESERVER
6. Teraz idziemy do datapacku i otwieramy:
gameserver/data/html/Tworzymy folder o nazwie:
NPCCRAFTERI tworzymy plik:
9999.htmW nim piszemy coś takiego:
<html><body>
Ivan:
[br /]
<font color="CCCC00">Witaj przybyszu! Mozesz u mnie krystalizowac i krafcic rozne rzeczy.</font></br>
<center>
<table width=240>
<tr>
<td><button value="Crystallize" action="bypass -h npc_%objectId%_Crystallize" width=120 height=25 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df"></td>
<td><button value="Manufacture" action="bypass -h npc_%objectId%_Manufacture" width=120 height=25 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df"></td>
</tr>
</table>
</center>[br /]
<center><img src="L2Font-e.mini_logo-e" width=250 height=85></center>
</body>
</html>
I zapisujemy. Możemy już skompilować DATAPACKA
Po zainstalowaniu bazy danych wystarczy dodać nowy rekord.
7. W tym celu wchodzimy do navicata, otwieramy naszą bazę danych wciskamy F6 i w konsoli która nam się pokaże wklejamy:
INSERT INTO `custom_npc` VALUES (
"9999", "30300", "Ivan", "1", "Craft Manager", "1", "LineageNPC.clear_npc", "7", "16", "70", "male", "L2CraftManager", "40", "4765", "2569", "4", "3", "40", "31", "24", "10", "65", "20", "0", "0", "1597", "2367", "4567", "1276", "798", "0", "1500", "0", "0", "0", "40", "120", "0", "1", "0", "0", "LAST_HIT", "0", "0", "0", "fighter", "false" );
I wciskamy Enter gdy wszystko zrobi poprawnie odpalamy nasz serwer i wpisujemy //spawn 9999
I cieszymy sie naszym nowym NPC!!!

Pozdrawiam!!!

EDIT: Przepraszam ale był mały błąd w kodzie do l2jmods.properties ale już wszystko ok. A co do tych praw to
POZWALAM WSZYSTKIM Z TEGO FORUM EDYTOWAĆ KOD

EDIT2: Nie wiem dlaczego ale z powodu cenzury na forum muszę podać link do pliku L2CraftManagerInstance.java. Gdyż nie mogę umieścić tutaj kodu bo strona zmienia niektóre linijki kodu w "-_-".


//Fro: Plusik.
« Ostatnia zmiana: Maj 23, 2010, 09:26:40 pm wysłana przez Frohike »