Jump to content
  • 0

[Java Code Help] Bioxazard Event (Zombies)


Question

Posted

Tha ithela na rwtisw an mporei kapoios na me boithisei me ena event pou thelw na perasw ston server mou Biohazard legete (Zombies).

To event trexei kanonika apla thelw na balw otan ksekinaei to event na kanei create ena item kai na to kanei equip kai prin na tous kanei teleport sto telos na to katastrefei..

 

dokimasa

pl.addItem("Biohazard", "13", pl, ,true);

pl.equipItem("Biohazard", "13", pl, ,true);

 

kai

 

pl.unEquipItem("Biohazard", "13", pl, ,true);

pl.destroyItem("Biohazard", "13", pl, ,true);

Alla pernw errors sto compile. An mporei kapoios na boithisei to ektimw para polu!!!

 

core patch (its for Gracia epilogue and i have changed the imports for Gracia Final

Index: java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java	(revision 3755)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java	(working copy)
@@ -136,6 +136,7 @@
import com.l2jserver.gameserver.model.base.PlayerClass;
import com.l2jserver.gameserver.model.base.Race;
import com.l2jserver.gameserver.model.base.SubClass;
+import com.l2jserver.gameserver.model.entity.Biohazard;
import com.l2jserver.gameserver.model.entity.Castle;
import com.l2jserver.gameserver.model.entity.Duel;
import com.l2jserver.gameserver.model.entity.Fort;
@@ -323,6 +324,7 @@
    };

	private static final int[] COMMON_CRAFT_LEVELS = { 5, 20, 28, 36, 43, 49, 55, 62 };
+	private static boolean _inBiohazard = false;

	public class AIAccessor extends L2Character.AIAccessor
	{
@@ -527,7 +529,19 @@
	private int _obsY;
	private int _obsZ;
	private boolean _observerMode = false;
+	
+	public boolean _isZombie = false;

+	public void setIsZombie(boolean a)
+	{
+		_isZombie = a;
+	}
+
+	public boolean isZombie()
+	{
+		return _isZombie;
+	}
+
	/** Stored from last ValidatePosition **/
	private Point3D _lastServerPosition = new Point3D(0, 0, 0);

@@ -4991,6 +5005,8 @@
    
    public void untransform()
    {
+		if (inBiohazard() && Biohazard.isStarted() && _transformation != null && isZombie())
+			return;
        if (_transformation != null)
        {
        	setTransformAllowedSkills(new int[]{});
@@ -5432,6 +5448,22 @@
		if (!super.doDie(killer))
			return false;

+		if (killer instanceof L2PcInstance)
+		{
+			L2PcInstance pl = (L2PcInstance) killer;
+			if (inBiohazard() && !isZombie() && pl.inBiohazard() && pl.isZombie() && Biohazard.isStarted())
+			{
+				pl.abortAttack();
+				pl.abortCast();
+				doRevive();
+				Biohazard.infectPlayer(this);
+				stopAllEffects();
+				setCurrentHp(getMaxHp());
+				setCurrentMp(getMaxMp());
+				setCurrentCp(getMaxCp());
+			}
+		}
+		
		if (isMounted())
			stopFeed();
		synchronized (this)
@@ -5582,6 +5614,18 @@
		{
			reviveRequest(this, null, false);
		}
+		
+		if (isZombie() && inBiohazard())
+		{
+			if (Biohazard._infected.contains(this))
+			{
+				Biohazard._infected.remove(this);
+				untransform();
+				if (Biohazard._infected.size() == 0)
+					Biohazard.playersWin();
+			}
+		}
+		
		return true;
	}

@@ -8529,7 +8573,17 @@
		// Check if the attacker isn't the L2PcInstance Pet
		if (attacker == this || attacker == getPet())
			return false;
-
+		
+		L2PcInstance player = null;
+		if (attacker instanceof L2PcInstance)
+			player = (L2PcInstance) attacker;
+		if (attacker instanceof L2SummonInstance)
+			player = ((L2SummonInstance) attacker).getOwner();
+		
+		if (player != null)
+			if (Biohazard.isStarted() && player.inBiohazard() && inBiohazard() && player.isZombie() != isZombie())
+				return true;
+		
		// TODO: check for friendly mobs
		// Check if the attacker is a L2MonsterInstance
		if (attacker instanceof L2MonsterInstance)
@@ -8918,6 +8972,9 @@
        	sendPacket(ActionFailed.STATIC_PACKET);
        	return false;
        }
+        
+		if (skill.getId() == 619 && inBiohazard() && isZombie())
+			return false;

        //************************************* Check Skill Type *******************************************

@@ -8929,7 +8986,24 @@
				// If L2Character or target is in a peace zone, send a system message TARGET_IN_PEACEZONE a Server->Client packet ActionFailed
				sendPacket(new SystemMessage(SystemMessageId.TARGET_IN_PEACEZONE));
				sendPacket(ActionFailed.STATIC_PACKET);
-				return false;
+				
+				boolean cond = true;
+				L2PcInstance trgtF = null;
+				if (target instanceof L2PcInstance)
+					trgtF = (L2PcInstance) target;
+				else if (target instanceof L2SummonInstance)
+					trgtF = ((L2SummonInstance) target).getOwner();
+				if (trgtF != null)
+					if (Biohazard.isStarted() && trgtF.inBiohazard() && inBiohazard())
+					{
+						if (trgtF.isZombie() != isZombie())
+							cond = true;
+						if (trgtF.isZombie() == isZombie())
+							cond = false;
+					}
+				
+				if (!cond)
+					return false;
			}

			if (isInOlympiadMode() && !isOlympiadStart()){
@@ -9357,6 +9431,8 @@
		{
			if(skill.isPvpSkill()) // pvp skill
			{
+				if (Biohazard.isStarted() && inBiohazard() && ((L2PcInstance)target).inBiohazard() && isZombie() != ((L2PcInstance)target).isZombie())
+					return true;
				if(getClan() != null && ((L2PcInstance)target).getClan() != null)
				{
					if(getClan().isAtWarWith(((L2PcInstance)target).getClan().getClanId()) && ((L2PcInstance)target).getClan().isAtWarWith(getClan().getClanId()))
@@ -9387,6 +9463,10 @@
		return true;
	}

+	private boolean inBiohazard() {
+		return _inBiohazard;
+	}
+
	/**
	 * Return True if the L2PcInstance is a Mage.<BR><BR>
	 */
@@ -11791,6 +11871,15 @@
			_log.log(Level.SEVERE, "deleteMe()", e);
		}

+		try
+		{
+			Biohazard.onLogout(this);
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.SEVERE, "deleteMe()", e);
+		}
+
		// Update database with items in its inventory and remove them from the world
		try
		{
@@ -13045,6 +13134,10 @@
	private int _afroId = 0;
	private boolean _isInSiege;

+	public int _oldX;
+	public int _oldY;
+	public int _oldZ;
+
    public Collection<TimeStamp> getReuseTimeStamps()
    {
        return _reuseTimeStamps.values();
@@ -14542,4 +14635,9 @@
			}
		}
	}
+
+	public void setIsInBiohazard(boolean b)
+	{
+		_inBiohazard = b;
+	}
}
\ No newline at end of file
Index: java/com/l2jserver/gameserver/model/entity/Biohazard.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/Biohazard.java	(revision 0)
+++ java/com/l2jserver/gameserver/model/entity/Biohazard.java	(revision 0)
@@ -0,0 +1,318 @@
+/*
+ * 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 com.l2jserver.gameserver.model.entity;
+
+import java.util.logging.Logger;
+
+import javolution.util.FastSet;
+
+import com.l2jserver.gameserver.Announcements;
+import com.l2jserver.gameserver.instancemanager.TransformationManager;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.olympiad.Olympiad;
+import com.l2jserver.util.Rnd;
+
+/**
+ * @author Laikeriz
+ */
+public class Biohazard
+{
+	enum EventState
+	{
+		INACTIVE, INACTIVATING, REGISTERING, STARTED, REWARDING
+	}
+	
+	private final static Logger _log = Logger.getLogger(Biohazard.class.getName());
+	private static EventState _state = EventState.INACTIVE;
+	
+	public static FastSet<L2PcInstance> _participants = new FastSet<L2PcInstance>();
+	public static FastSet<L2PcInstance> _infected = new FastSet<L2PcInstance>();
+	public static FastSet<L2PcInstance> _notInfected = new FastSet<L2PcInstance>();
+	
+	public static boolean isStarted()
+	{
+		if (_state == EventState.STARTED)
+			return true;
+		return false;
+	}
+	
+	public static boolean isRegistering()
+	{
+		if (_state == EventState.REGISTERING)
+			return true;
+		return false;
+	}
+	
+	public static void startRegistering()
+	{
+		if (_state == EventState.REGISTERING || _state == EventState.STARTED)
+			return;
+		Announcements.getInstance().announceToAll("Biohazard: Registration is open.");
+		Announcements.getInstance().announceToAll("Biohazard: Type \".bhreg\" to register to event.");
+		Announcements.getInstance().announceToAll("Biohazard: Type \".bhunreg\" to unregister from event.");
+		_state = EventState.REGISTERING;
+		int step = 0;
+		int after = 0;
+		for (int i = 40; i > 0; i -= 10)
+		{
+			switch (i)
+			{
+				case 40:
+					step = 5;
+					after = 15;
+					break;
+				case 30:
+					step = 5;
+					after = 10;
+					break;
+				case 20:
+					step = 4;
+					after = 5;
+					break;
+				case 10:
+					step = 1;
+					after = 1;
+					break;
+			}
+			if (_state == EventState.INACTIVE)
+				return;
+			Announcements.getInstance().announceToAll("Biohazard: Registration will be closed in " + after + " minute(s).");
+			try
+			{
+				Thread.sleep(step * 60000);
+			}
+			catch (Exception e)
+			{
+			}
+		}
+		//sound = "";
+		try
+		{
+			Thread.sleep(60000);
+		}
+		catch (Exception e)
+		{
+		}
+		if (_state == EventState.INACTIVE)
+			return;
+		if (_participants.size() >= 2)
+		{
+			Announcements.getInstance().announceToAll("Biohazard: Teleporting players in 20 seconds.");
+			try
+			{
+				Thread.sleep(20000);
+			}
+			catch (Exception e)
+			{
+			}
+			_state = EventState.STARTED;
+			startEventAndTelePl();
+		}
+		else
+			Announcements.getInstance().announceToAll("Biohazard: Event aborted due to lack of participants.");
+	}
+	
+	public static void addParticipant(L2PcInstance player)
+	{
+		if (Olympiad.getInstance().isRegistered(player) || TvTEvent.isPlayerParticipant(player.getObjectId()))
+		{
+			player.sendMessage("You cannot register because of registration in another event");
+			return;
+		}
+		if (_state == EventState.REGISTERING && !_participants.contains(player))
+		{
+			_participants.add(player);
+			player.sendMessage("You have successfully registered to this event");
+		}
+		else
+			player.sendMessage("You are already registered or it's not registration time.");
+	}
+	
+	public static void removeParticipant(L2PcInstance player)
+	{
+		if (_state == EventState.REGISTERING)
+		{
+			if (_participants.contains(player))
+				_participants.remove(player);
+			else
+				player.sendMessage("You aren't registered in this event.");
+			player.setIsInBiohazard(false);
+		}
+		else
+			player.sendMessage("It's not registration time.");
+	}
+	
+	public static void startEventAndTelePl()
+	{
+		if (_state == EventState.INACTIVE)
+			return;
+		synchronized (_participants)
+		{
+			for (L2PcInstance pl : _participants)
+				if (pl.isOnline() == 1)
+				{
+					_notInfected.add(pl);
+					pl._oldX = pl.getX();
+					pl._oldY = pl.getY();
+					pl._oldZ = pl.getZ();
+					pl.teleToLocation(-17507, 143206, -3911);
+					pl.setTeam(0);
+					pl.setIsInBiohazard(true);
+					pl.untransform();
+				}
+		}
+		Announcements.getInstance().announceToAll("Biohazard: Teleportion done.");
+		Announcements.getInstance().announceToAll("Biohazard: One player was infected by untreatable virus!");
+		Announcements.getInstance().announceToAll("Biohazard: In about one minute virus will take over his body and he will become zombie!");
+		try
+		{
+			Thread.sleep(60000);
+		}
+		catch (Exception e)
+		{
+		}
+		int num = Math.round(Rnd.get(_notInfected.size() - 1));
+		L2PcInstance infectFirst = ((L2PcInstance[]) getAllNotInfected())[num];
+		infectPlayer(infectFirst);
+		Announcements.getInstance().announceToAll("Biohazard: Virus took over " + infectFirst.getName() + " body and he wants to infect everybody else!");
+	}
+	
+	public static void infectPlayer(L2PcInstance zombie)
+	{
+		if (_state == EventState.INACTIVE)
+			return;
+		if (zombie.isTransformed())
+			zombie.untransform();
+		zombie.setIsZombie(true);
+		_notInfected.remove(zombie);
+		_infected.add(zombie);
+		TransformationManager.getInstance().transformPlayer(303, zombie);
+		if (_notInfected.size() == 0)
+			zombiesWin();
+	}
+	
+	public static void onLogout(L2PcInstance playerInstance)
+	{
+		if (_state == EventState.REGISTERING)
+			removeParticipant(playerInstance);
+		else if (_state == EventState.STARTED)
+		{
+			playerInstance.setXYZ(playerInstance._oldX, playerInstance._oldY, playerInstance._oldZ);
+			if (!playerInstance.isZombie())
+				_notInfected.remove(playerInstance);
+			else if (playerInstance.isZombie())
+				_infected.remove(playerInstance);
+			if (_notInfected.size() == 0)
+				zombiesWin();
+			if (_infected.size() == 0)
+				playersWin();
+		}
+	}
+	
+	public static void zombiesWin()
+	{
+		if (_state == EventState.INACTIVE)
+			return;
+		Announcements.getInstance().announceToAll("Biohazard: Zombies won.");
+		Announcements.getInstance().announceToAll("Biohazard: Rewarding and teleporting participants back to village in 20 seconds.");
+		_state = EventState.REWARDING;
+		try
+		{
+			Thread.sleep(20000);
+		}
+		catch (Exception e)
+		{
+		}
+		synchronized (_infected)
+		{
+			for (L2PcInstance pl : _infected)
+				if (pl.isOnline() == 1)
+					pl.addItem("Biohazard", 6673, 1, pl, true);
+		}
+		synchronized (_participants)
+		{
+			for (L2PcInstance pl : _participants)
+				if (pl.isOnline() == 1)
+				{
+					pl.teleToLocation(pl._oldX, pl._oldY, pl._oldZ);
+					pl.setIsInBiohazard(false);
+					//					if (pl.inWorld() == 1)
+					//						pl.setTeam(pl.getFactionId());
+					if (pl.isTransformed())
+						pl.untransform();
+				}
+		}
+		_participants.clear();
+		_infected.clear();
+		_notInfected.clear();
+		_state = EventState.INACTIVE;
+	}
+	
+	public static void playersWin()
+	{
+		Announcements.getInstance().announceToAll("Biohazard: Players won.");
+		Announcements.getInstance().announceToAll("Biohazard: Rewarding and teleporting participants back to village in 20 seconds.");
+		_state = EventState.REWARDING;
+		try
+		{
+			Thread.sleep(20000);
+		}
+		catch (Exception e)
+		{
+		}
+		synchronized (_notInfected)
+		{
+			for (L2PcInstance pl : _notInfected)
+				if (pl.isOnline() == 1)
+				{
+					pl.addItem("Biohazard", 6673, 1, pl, true);
+				}
+		}
+		synchronized (_participants)
+		{
+			for (L2PcInstance pl : _participants)
+				if (pl.isOnline() == 1)
+				{
+					pl.teleToLocation(pl._oldX, pl._oldY, pl._oldZ);
+					pl.setIsInBiohazard(false);
+					//					if (pl.inWorld() == 1)
+					//						pl.setTeam(pl.getFactionId());
+					if (pl.isTransformed())
+						pl.untransform();
+				}
+		}
+		_participants.clear();
+		_infected.clear();
+		_notInfected.clear();
+		_state = EventState.INACTIVE;
+	}
+	
+	public static L2PcInstance[] getAllNotInfected()
+	{
+		synchronized (_notInfected)
+		{
+			return _notInfected.toArray(new L2PcInstance[_notInfected.size()]);
+		}
+	}
+	
+	public static void abortEvent()
+	{
+		_state = EventState.INACTIVE;
+		_participants.clear();
+		_notInfected.clear();
+		_infected.clear();
+		Announcements.getInstance().announceToAll("Biohazard: Event aborted.");
+	}
+}

 

 

datapack patch

Index: data/scripts/handlers/MasterHandler.java
===================================================================
--- data/scripts/handlers/MasterHandler.java	(revision 6783)
+++ data/scripts/handlers/MasterHandler.java	(working copy)
@@ -231,6 +231,7 @@
			VoicedCommandHandler.getInstance().registerVoicedCommandHandler(new Banking());
		if (Config.TVT_ALLOW_VOICED_COMMAND)
			VoicedCommandHandler.getInstance().registerVoicedCommandHandler(new TvTVoicedInfo());
+		VoicedCommandHandler.getInstance().registerVoicedCommandHandler(new biohazard());
		_log.config("Loaded " + VoicedCommandHandler.getInstance().size() + " VoicedHandlers");
	}

Index: data/scripts/handlers/admincommandhandlers/AdminEventEngine.java
===================================================================
--- data/scripts/handlers/admincommandhandlers/AdminEventEngine.java	(revision 6783)
+++ data/scripts/handlers/admincommandhandlers/AdminEventEngine.java	(working copy)
@@ -33,6 +33,7 @@
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Biohazard;
import com.l2jserver.gameserver.model.entity.L2Event;
import com.l2jserver.gameserver.network.serverpackets.CharInfo;
import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
@@ -75,7 +76,9 @@
		"admin_event_control_unpoly",
		"admin_event_control_prize",
		"admin_event_control_chatban",
-		"admin_event_control_finish"
+		"admin_event_control_finish",
+		"admin_bh_start",
+		"admin_bh_abort"
	};

	private static String tempBuffer = "";
@@ -138,7 +141,6 @@
			showMainPage(activeChar);

		}
-		
		else if (command.startsWith("admin_event_name"))
		{
			tempName += command.substring(17);
@@ -158,7 +160,6 @@
				tempBuffer = "";
			}
		}
-		
		else if (command.startsWith("admin_event_store"))
		{

@@ -383,6 +384,14 @@
			adminReply.setHtml(replyMSG);
			activeChar.sendPacket(adminReply);
		}
+		else if (command.equals("admin_bh_start"))
+		{
+			Biohazard.startRegistering();
+		}
+		else if (command.equals("admin_bh_abort"))
+		{
+			Biohazard.abortEvent();
+		}

		return true;
	}
Index: data/scripts/handlers/voicedcommandhandlers/biohazard.java
===================================================================
--- data/scripts/handlers/voicedcommandhandlers/biohazard.java	(revision 0)
+++ data/scripts/handlers/voicedcommandhandlers/biohazard.java	(revision 0)
@@ -0,0 +1,50 @@
+/*
+ * 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 handlers.voicedcommandhandlers;
+
+import com.l2jserver.gameserver.handler.IVoicedCommandHandler;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Biohazard;
+
+/**
+*
+*
+*/
+public class biohazard implements IVoicedCommandHandler
+{
+	private static final String[] VOICED_COMMANDS = { "bhreg", "bhunreg" };
+	
+	/**
+	 * 
+	 * @see com.l2jserver.gameserver.handler.IVoicedCommandHandler#useVoicedCommand(java.lang.String, com.l2jserver.gameserver.model.actor.instance.L2PcInstance, java.lang.String)
+	 */
+	public boolean useVoicedCommand(String command, L2PcInstance activeChar, String params)
+	{
+		if (command.equalsIgnoreCase("bhreg"))
+			Biohazard.addParticipant(activeChar);
+		else if (command.equalsIgnoreCase("bhunreg"))
+			Biohazard.removeParticipant(activeChar);
+		return true;
+	}
+	
+	/**
+	 * 
+	 * @see com.l2jserver.gameserver.handler.IVoicedCommandHandler#getVoicedCommandList()
+	 */
+	public String[] getVoicedCommandList()
+	{
+		return VOICED_COMMANDS;
+	}
+}
Index: sql/admin_command_access_rights.sql
===================================================================
--- sql/admin_command_access_rights.sql	(revision 6838)
+++ sql/admin_command_access_rights.sql	(working copy)
@@ -537,4 +537,8 @@

-- ZONE
('admin_zone_check','1'),
-('admin_zone_reload','1');
\ No newline at end of file
+('admin_zone_reload','1'),
+
+-- Biohazard event
+('admin_bh_abort', '1'),
+('admin_bh_start', '1');
\ No newline at end of file

 

Ean mporeite na boithisete sas euxaristw polu!!!!

3 answers to this question

Recommended Posts

  • 0
Posted

lol sevikovic den eine diko tou den to kanei share apla leei poio code exei kai ti 8elei na kanei  kele pm autone p xei ton code na sto pei..autos ton eftia3e autos 8a 3erei tin apantisi ;D

  • 0
Posted

lol sevikovic den eine diko tou den to kanei share apla leei poio code exei kai ti 8elei na kanei  kele pm autone p xei ton code na sto pei..autos ton eftia3e autos 8a 3erei tin apantisi ;D

ela more den to katalaves aplo spamm ekane :P

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Posts

    • Super responsive, clearly understood what I needed, and delivered everything on time — even going the extra mile with small details I hadn’t thought of. The CMS looks amazing and runs flawlessly on all devices. If you’re looking for reliable, skilled, and easy-to-work-with web devs, I 100% recommend him.
    • Hello guys, I’d like to introduce your audience to my original project, which has gained popularity in Europe and among the Russian-speaking community. I just never got around to posting about it here until now. At one point, I wanted to develop a launcher (game file downloader) in the browser, and that idea eventually evolved into a full-fledged CMS engine with extensive functionality. SphereWeb is a massive ecosystem for Lineage 2 JAVA servers, packed with everything a server administrator and players might need. From October 2024 to April 24, 2025, my project has been installed on 250 different domains. SphereWeb is your best choice — a modern web engine designed specifically for administrators of Lineage 2 Java game servers. It offers a rich and user-friendly interface for managing your server with ease. ✅ Player Control Panel – covers all player needs: Authorization, registration, password change, account linking and synchronization, contacting the admin via support system, teleporting a character (and sending items to warehouse) to a town, warehouse management (sending items in-game), and making server donations. ✅ Admin Control Panel – opens up new horizons, giving you access to: Extensive panel customization (more on this later) Donation history with charts News and page creation Stream management (add streams) Item shop creation Starter packs creation Bonus code generation XenForo news integration Email message settings Global activity log Traffic insights (track where your users come from) Extensions section (plugins – more on that later) Server management Auto software updates Tech support Custom translations Now, about the Control Panel settings: The standard settings are organized into several tabs: Language There are 5 available languages: Russian, English, Spanish, Portuguese, and Greek, covering 99% of translation needs. You can also set a default language for the panel.   Features Toggle built-in features of the control panel: News, Shop, Balance, Statistics, Support, Balance Transfer, Bonus Code, Streams, Data Emulation. Enable/disable options to keep the panel clean and focused on what you need. Captcha Support for Google reCAPTCHA, Cloudflare Turnstile, or default hCaptcha. Old-school recommendation: use Google reCAPTCHA v2. Fake Online Boosting Basic settings for boosting the online counter. Registration Settings Configuration options for the registration process. Email Connect your panel to an SMTP server. Misc General-purpose settings and adjustments. Template Choose and preview the design template for your landing page. Logo Upload your control panel logo and favicon. Palette Customize the color scheme of your control panel interface. Menu Add links to your site’s navigation menu. Background Upload high-resolution background images for login, registration, and password recovery pages. Notifications Set up Telegram notifications for selected events. In Sphere 2, I’ve paid special attention to plugins, making it easy to add and expand functionality. By default, the panel includes several built-in extensions (plugins).   Giveaway – allows you to host item giveaways for users directly on the website. Internal Forum – a built-in forum system inside the Control Panel (more details on it below). Launcher – a free solution for updating game files. It delivers unmatched speed and runs directly in the browser, allowing full design customization. Traders – (currently for Lucera2 only) displays a list of offline shops, their items, prices, and player locations directly on the website. Roulette – a fun game where users spin the wheel to win items. Item Editor – a tool for creating custom in-game items. Item Increase – tracks and displays item count by ID across the server in graph form, showing which players hold the most. Registration Statistics – a simple chart showing registration trends over time. SQL Collection – a plugin for adding or adjusting Java server builds if your current build isn’t supported or needs customization. ✅ Supported Java Server Builds The system currently supports a variety of popular Java server builds. Full list available in the admin panel. 🧩 Forum Plugin In the first version of Sphere, a basic internal forum was quite popular among server admins — so in Sphere 2, it came back better than ever. Inspired by XenForo, the forum is rich in features and designed for both community and solo players: Players can create clan communities to connect and play together. Clan creators can upload clan logos and header banners, customize text color for the clan name. Clan members can post on the public clan wall or chat in a dedicated clan chat. Clan logos and banners appear across the forum for all members. For players who like to show off: Under each username, the forum can display PvP/PK stats, in-game time, and character list. Players can choose to hide this data if they prefer privacy. Admins can assign moderator roles to users for specific forum sections, ensuring proper content management and community moderation.   💰 Donations & Rewards The administrator has a wide range of reward settings for player donations — almost every suggested method has been implemented: Cumulative discount system – discounts increase as the total donation amount grows. One-time bonus – an extra reward for a specific donation. Permanent shop discounts – based on the player's total donation history. One-time item shop discounts – also based on total donations. Item-based rewards – configurable rewards delivered automatically after donation. ✅ Supported Payment Systems (Current list is available in the admin panel and may vary by region.) 🔄 SphereWeb Auto-Update System Sphere is actively developed — I improve it almost daily. To ensure everyone stays updated, I’ve implemented multiple update methods: Automatic – once I push updates to GitHub, they are downloaded to Sphere clients within 5 minutes. Manual – if automatic updates are disabled or your site was offline during update release, you can trigger the update manually with one click. File Scanner – this feature scans your Sphere installation, compares files with the latest version, and shows missing or modified files you can restore. 📸 Control Panel Screenshots (Here you’d typically show screenshots or say where they can be found.)   💬 Final Words A lot of work has gone into this project. I occasionally post updates in the Sphere Telegram channel — when I don’t forget. I’m truly proud of the results. 🚀 Want to Install It? Before you rush in, please note: Installation won’t work on localhost. A valid SSL certificate is required. Repo: GitHub - Cannabytes/SphereWeb2 Upload the archive to your hosting. Open your website in the browser — the installer will guide you. ⚠️ Some Russian hosting providers block wide IP ranges, which may interfere with installation. 💸 Pricing Three usage plans available: Free – limited to 20 game account registrations per day. $12.5/month – no Sphere limitations. $20/month – no Sphere limitations + access to all commercial plugins. Your balance is shown in the admin panel, and you can renew access anytime. ✅ All users receive updates, regardless of subscription tier. A lot of work has been done, and from time to time I share updates in the Sphere Telegram channel — when I don’t forget. I’m truly proud of what I’ve built. Did you like it? Want to install it yourself? Please note — you won’t be able to install it on a local server. A valid SSL certificate is also required. Steps to install: Download the package from the GitHub repository: Cannabytes/SphereWeb2 Extract the archive on your hosting. Open your website in a browser — the installer will launch automatically. Just follow the instructions. 🔧 Minimum Requirements: PHP 8.2 MariaDB or MySQL 5.8 SSL certificate for your website   💵 Pricing SphereWeb offers 3 usage options: Free Plan – limited to 20 game account registrations per day. $12.5/month – no limitations, full access to Sphere features. 3. $20/month – no limitations + access to all commercial plugins. Your current balance is shown in the admin panel, and you can renew your license whenever you wish. Regardless of your plan, you will always receive updates. 🆕 Latest Updates: User Registration Source Tracking: Now, when a user registers, you can see where they came from before landing on the site via Telegram notifications. Bulk Deletion of Bonus Codes: Added functionality to bulk delete bonus codes for better management. Starter Pack Editor: A new editor for creating and managing starter packs is now available. Item Removal from Warehouse: Admins can now remove items from a user's warehouse. Server-Specific Settings: Each server now has a "Functions" button, providing additional customization options for each server. Warehouse Cleanup: Admins can now clear the warehouse for all users or by specific item ID. Custom Return Button: The "Return to Site" button can now be disabled, and you can set a custom link for it. Character List UI Overhaul: The character list in the admin panel has been redesigned to be more minimalist and user-friendly. User Info Page Improvements: The user information page has been enhanced for better navigation and access to key data. Donation History Updates: The donation history page has been improved for better data presentation. Item Stacking and Splitting: Users can now stack or split identical items (e.g., ID 57 (150) + ID 150 = ID 57 (300)). Admins can configure which items can be stacked and split. Account Deletion: Users now have the option to delete their own accounts from the account list. Success Chest Plugin: A new "Success Chest" plugin has been added, allowing admins to define chests with specific items, their prices, and visual parameters. Reworked Warehouse: The warehouse now operates in a separate modal window. When items are purchased, they are automatically added to the warehouse without page reloads. Registration Reward: Admins now have the ability to reward users for registration, adding more incentives. Item Stacking and Splitting Customization: Admins can now specify which items players can split and stack in their warehouse. These settings are available in the admin panel under the server's "Functions" button, offering granular control over item management. Account Deletion Feature: Players now have the ability to remove their accounts from the account list (but not from the server). In the future, this feature will be customizable for each server. Success Chest Plugin: A new "Success Chest" plugin has been added, allowing admins to define the items inside the chest. Players can then randomly draw one item from the chest. This feature is still in early testing, and any feedback or issues will be addressed in future updates. Improved Warehouse/Inventory: The warehouse/inventory system has been enhanced. Now, when items (such as starter packs or chests) are purchased, they are immediately added to the warehouse without requiring a page refresh. Additionally, the modal window for the warehouse now opens when the warehouse button is clicked with the mouse wheel. 😊 Log Sorting by Server: Logs now include the ability to sort by server, making it easier to manage and review data for each individual server. Registration Source Tracking: Telegram notifications now include information about where a user came from before registering on your site. Bulk Deletion of Bonus Codes: Admins can now bulk delete server-specific bonus codes, as well as bonus codes that were generated for all servers. Customizable Starter Packs: A new option has been added to modify and customize starter packs, giving more flexibility to server admins. Item Removal from Warehouse in Profile: Admins can now remove items from a user's warehouse directly from their profile. "Functions" Button in Admin Panel: A new "Functions" button has been added to the admin panel, offering additional tools for server management. This includes the ability to clear the server’s warehouse entirely or by specific item ID. Disabling the "Return to Site" Button: Under Admin Panel -> Settings -> Miscellaneous, there is now an option to disable the "Return to Site" button in the site menu
    • We are waiting you today at 8pm +3 GMT website: https://l2evo.net The patch will be available 30 min before the grand opening. Come join the best Interlude pvp server.  
    • We are certainly not an ambulance, but we will definitely cure you of blacklists and empty pockets. Live freely with SX! Each of you will receive a trial version of SX to familiarize yourself with the product, all you have to do is post in this thread
  • Topics

×
×
  • Create New...