Jump to content

Recommended Posts

Posted (edited)

Hello,
I created this vote manager when I needed it for my server.Basically,you have to type /vote go get this html window:

vote.png

Then by clicking on any of the buttons will give you 60seconds to vote for the server.

/*
 * 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.usercommandhandlers;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.EnumMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import net.sf.l2j.Config;
import net.sf.l2j.L2DatabaseFactory;
import net.sf.l2j.gameserver.ThreadPoolManager;
import net.sf.l2j.gameserver.handler.IUserCommandHandler;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;

/**
 * @author Eimantas
 */
public class VotingReward implements IUserCommandHandler
{
    // Queries
    private static final String DELETE_QUERY = "DELETE FROM mods_voting_reward WHERE time < ?";
    private static final String SELECT_QUERY = "SELECT * FROM mods_voting_reward";
    private static final String INSERT_QUERY = "INSERT INTO mods_voting_reward (data, scope, time, top) VALUES (?, ?, ?, ?)";

    private static final Logger _log = Logger.getLogger(VotingReward.class.getName());

    private static final long VOTING_INTERVAL = TimeUnit.HOURS.toMillis(12);

    private static final Map<UserScope, ScopeContainer> VOTTERS_CACHE = new EnumMap<>(UserScope.class);

    public static long TimeToVote = TimeUnit.SECONDS.toMillis(60);
    static boolean isVotingHopzone = false;
    static boolean isVotingTopzone = false;
    public static String TopzoneURL = Config.TOPZONE_SERVER_LINK;
    public static String HopZoneURL = Config.HOPZONE_SERVER_LINK;
    
    static final int[] COMMANDS =
    {
        115
    };
    
    public VotingReward()
    {
        load();
    }
    
    @Override
    public boolean useUserCommand(int id, L2PcInstance activeChar)
    {
        if (id == COMMANDS[0])
        {
            showVoteHtml(activeChar);
        }
        return false;
    }
    
    @Override
    public int[] getUserCommandList()
    {
        return COMMANDS;
    }
    
    public static void showVoteHtml(L2PcInstance player)
    {
        NpcHtmlMessage html = new NpcHtmlMessage(0);
        html.setFile("data/html/managers/vote.htm");
        player.sendPacket(html);
    }
    
    public static void voteHopzone(L2PcInstance player)
    {
        final L2PcInstance player2 = player;
        showVoteHtml(player2);
        long time = getLastVotedTime(player, "hopzone");
        if (player2.isVoting())
        {
            player2.sendMessage("You are already voting!");
            return;
        }
        if (time > 0)
        {
            sendReEnterMessage(time, player);
            return;
        }
        if (isVotingHopzone)
        {
            player2.sendMessage("Someone is already voting.Please wait!");
            return;
        }
        final int currVotes = getHopzoneCurrentVotes();
        isVotingHopzone = true;

        player2.sendMessage("You have " + TimeToVote / 1000 + " seconds to vote for us on HopZone!");
        player2.setVoting(true);
        ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
        {
            @Override
            public void run()
            {
                if (getHopzoneCurrentVotes() > currVotes)
                {
                    player2.sendMessage("Thank You for voting!");
                    markAsVotted(player2, "hopzone");
                    giveReward(player2);
                }
                else
                {
                    player2.sendMessage("You did not vote for server!");
                }
                isVotingHopzone = false;
                player2.setVoting(false);
            }
        }, TimeToVote);

    }
    
    public static void voteTopzone(L2PcInstance player)
    {
        final L2PcInstance player2 = player;
        showVoteHtml(player2);
        long time = getLastVotedTime(player, "topzone");
        if (player2.isVoting())
        {
            player2.sendMessage("You are already voting!");
            return;
        }
        if (time > 0)
        {
            sendReEnterMessage(time, player);
            return;
        }
        if (isVotingTopzone)
        {
            player2.sendMessage("Someone is already voting.Please wait!");
            return;
        }
        final int currVotes = getTopzoneCurrentVotes();
        isVotingTopzone = true;
        player2.sendMessage("You have " + TimeToVote / 1000 + " seconds to vote for us on Topzone!");
        player2.setVoting(true);
        ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
        {
            @Override
            public void run()
            {
                if (getTopzoneCurrentVotes() > currVotes)
                {
                    player2.sendMessage("Thank You for voting!");
                    markAsVotted(player2, "topzone");
                    giveReward(player2);
                }
                else
                {
                    player2.sendMessage("You did not vote for server!");
                }
                isVotingTopzone = false;
                player2.setVoting(false);
            }
        }, TimeToVote);

    }
    
    public static int getHopzoneCurrentVotes()
    {
        InputStreamReader isr = null;
        BufferedReader br = null;
        
        try
        {
            if (!HopZoneURL.endsWith(".html"))
                HopZoneURL += ".html";
            
            URLConnection con = new URL(HopZoneURL).openConnection();
            
            con.addRequestProperty("User-L2Hopzone", "Mozilla/4.76");
            isr = new InputStreamReader(con.getInputStream());
            br = new BufferedReader(isr);
            
            String line;
            while ((line = br.readLine()) != null)
            {
                if (line.contains("no steal make love") || line.contains("no votes here") || line.contains("bang, you don't have votes") || line.contains("la vita e bella"))
                {
                    int votes = Integer.valueOf(line.split(">")[2].replace("</span", ""));
                    return votes;
                }
            }
            
            br.close();
            isr.close();
        }
        catch (Exception e)
        {
            System.out.println(e);
            System.out.println("Error while getting server vote count on HopZone.");
            _log.log(Level.WARNING, "Error while getting server vote count on HopZone!");
        }

        return -1;
    }
    
    public static int getTopzoneCurrentVotes()
    {
        InputStreamReader isr = null;
        BufferedReader br = null;

        try
        {
            URLConnection con = new URL(TopzoneURL).openConnection();
            con.addRequestProperty("User-Agent", "L2TopZone");
            isr = new InputStreamReader(con.getInputStream());
            br = new BufferedReader(isr);

            boolean got = false;

            String line;
            while ((line = br.readLine()) != null)
            {
                if (line.contains("<div class=\"rank\"><div class=\"votes2\">Votes:<br>") && !got)
                {
                    got = true;
                    int votes = Integer.valueOf(line.split("<div class=\"rank\"><div class=\"votes2\">Votes:<br>")[1].replace("</div></div>", ""));
                    return votes;
                }
            }

            br.close();
            isr.close();
        }
        catch (Exception e)
        {
            System.out.println(e);
            System.out.println("Error while getting server vote count on Topzone.");
            _log.log(Level.WARNING, "Error while getting server vote count on Topzone!");
        }

        return -1;
    }
    
    private static final long getLastVotedTime(L2PcInstance activeChar, String top)
    {
        for (Entry<UserScope, ScopeContainer> entry : VOTTERS_CACHE.entrySet())
        {
            final String data = entry.getKey().getData(activeChar);
            final long reuse = entry.getValue().getReuse(data, top);
            if (reuse > 0)
            {
                return reuse;
            }
        }
        return 0;
    }

    private static void sendReEnterMessage(long time, L2PcInstance player)
    {
        if (time > System.currentTimeMillis())
        {
            final long remainingTime = (time - System.currentTimeMillis()) / 1000;
            final int hours = (int) (remainingTime / 3600);
            final int minutes = (int) ((remainingTime % 3600) / 60);
            final int seconds = (int) ((remainingTime % 3600) % 60);

            String msg = "You have received your reward already try again in: " + hours + " hours";
            if (minutes > 0)
            {
                msg += " " + minutes + " minutes";
            }
            if (seconds > 0)
            {
                msg += " " + seconds + " seconds";
            }
            player.sendMessage(msg);
        }
    }

    private static final void load()
    {
        // Initialize the cache
        for (UserScope scope : UserScope.values())
        {
            VOTTERS_CACHE.put(scope, new ScopeContainer());
        }

        // Cleanup old entries and load the data for votters
        try (Connection con = L2DatabaseFactory.getInstance().getConnection(); PreparedStatement ps = con.prepareStatement(DELETE_QUERY); Statement st = con.createStatement())
            {
            ps.setLong(1, System.currentTimeMillis());
            ps.execute();

            // Load the data
            try (ResultSet rset = st.executeQuery(SELECT_QUERY))
            {
                while (rset.next())
                {
                    final String data = rset.getString("data");
                    final UserScope scope = UserScope.findByName(rset.getString("scope"));
                    final Long time = rset.getLong("time");
                    final String top = rset.getString("top");
                    if (scope != null)
                    {
                        VOTTERS_CACHE.get(scope).registerVotter(data, time, top);
                    }
                }
            }
            }
        catch (SQLException e)
        {
            _log.log(Level.WARNING, VotingReward.class.getSimpleName() + ": " + e.getMessage(), e);
        }
    }

    private enum UserScope
    {
        ACCOUNT
        {
            @Override
            public String getData(L2PcInstance player)
            {
                return player.getAccountName();
            }
        },
        IP
        {
            @Override
            public String getData(L2PcInstance player)
            {
                return player.getClient().getConnection().getInetAddress().getHostAddress();
            }
        },
        //@formatter:off
        /*HWID
        {
            @Override
            public String getData(L2PcInstance player)
            {
                return player.getHWID();
            }
        }*/
        //@formatter:on
        ;

        public abstract String getData(L2PcInstance player);

        public static UserScope findByName(String name)
        {
            for (UserScope scope : values())
            {
                if (scope.name().equals(name))
                {
                    return scope;
                }
            }
            return null;
        }
    }

    private static class ScopeContainer
    {
        private final Map<String, Long> _HopzoneVotters = new ConcurrentHashMap<>();
        private final Map<String, Long> _TopzoneVotters = new ConcurrentHashMap<>();

        public ScopeContainer()
        {
        }

        public void registerVotter(String data, long reuse, String top)
        {
            if (top.equalsIgnoreCase("hopzone"))
            {
                _HopzoneVotters.put(data, reuse);
            }
            if (top.equalsIgnoreCase("topzone"))
            {
                _TopzoneVotters.put(data, reuse);
            }
        }

        public long getReuse(String data, String top)
        {
            if (top.equalsIgnoreCase("hopzone"))
            {
                if (_HopzoneVotters.containsKey(data))
                {
                    long time = _HopzoneVotters.get(data);
                    if (time > System.currentTimeMillis())
                    {
                        return time;
                    }
                }
            }
            if (top.equalsIgnoreCase("topzone"))
            {
                if (_TopzoneVotters.containsKey(data))
                {
                    long time = _TopzoneVotters.get(data);
                    if (time > System.currentTimeMillis())
                    {
                        return time;
                    }
                }
            }
            return 0;
        }
    }

    static void markAsVotted(L2PcInstance player, String top)
    {
        final long reuse = System.currentTimeMillis() + VOTING_INTERVAL;
        try (Connection con = L2DatabaseFactory.getInstance().getConnection(); PreparedStatement ps = con.prepareStatement(INSERT_QUERY))
            {
            for (UserScope scope : UserScope.values())
            {
                final String data = scope.getData(player);
                final ScopeContainer container = VOTTERS_CACHE.get(scope);
                container.registerVotter(data, reuse, top);

                ps.setString(1, data);
                ps.setString(2, scope.name());
                ps.setLong(3, reuse);
                ps.setString(4, top);
                ps.addBatch();
            }
            ps.executeBatch();
            }
        catch (SQLException e)
        {
            _log.log(Level.WARNING, VotingReward.class.getSimpleName() + ": " + e.getMessage(), e);
        }
    }
    
    static void giveReward(L2PcInstance player)
    {
        player.addItem("Reward", 6673, 1, player, true);
    }
    
}

Add those to net.sf.l2j.Config:

public static String TOPZONE_SERVER_LINK;
public static String HOPZONE_SERVER_LINK;
HOPZONE_SERVER_LINK = votemanager.getProperty("HopzoneServerLink", "http://l2.hopzone.net/lineage2/details/98632/L2-cyrex/");
TOPZONE_SERVER_LINK = votemanager.getProperty("TopzoneServerLink", "http://l2topzone.com/lineage2/server-info/11321/L2Cyrex.html/");

and to net.sf.l2j.gameserver.handler.UserCommandHandler this:

registerUserCommandHandler(new VotingReward());

SQL:
 

DROP TABLE IF EXISTS `mods_voting_reward`;
CREATE TABLE `mods_voting_reward` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `data` varchar(255) NOT NULL,
  `scope` varchar(255) NOT NULL,
  `time` bigint(20) unsigned NOT NULL,
  `top` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=55 DEFAULT CHARSET=utf8;

Changing reward(Last lines of VotingReward):

    static void giveReward(L2PcInstance player)
    {
        player.addItem("Reward", ITEM ID , ITEM COUNT , player, true);
    }

Config(votemanager.properties):
 

HopzoneServerLink = http://l2.hopzone.net/lineage2/details/98632/L2-cyrex/
TopzoneServerLink = http://l2topzone.com/lineage2/server-info/11321/L2Cyrex.html/

This is probably poorly coded,just wanted to share,some pieces are taken from An4rchy vote manager.
Also Client side(commandname-e.dat):

116	115	vote

EDIT:Vote.html
 

<html>
<body>
       <center>
	   <p>Vote Manager:</p>
	   <br><br><br><br><br><br><br><br><br><br><br><br>
	   <button value="Vote for us on HopZone" action="bypass -h vote-hopzone" width=180 height=20 back="YourTexture" fore="YourTexture"/>
	   <img src=L2UI_CH3.herotower_deco width=256 height=32>
	   <button value="Vote for us on Topzone" action="bypass -h vote-topzone" width=180 height=20 back="YourTexture" fore="YourTexture"/>
	   </center>
</body>
</html>

Ofc,you have to change YourTexture to....

L2PcInstance.java
 

        boolean isVoting = false;	
        public boolean isVoting()
	{
		return isVoting;
	}
	
	public void setVoting(boolean voting)
	{
		isVoting = voting;
	}

Good luck!
 

Edited by StealthyS4m
Posted

is it tested that the hopzone link works?

i passed the part that reads the hopzone vote in my individual and still doesn't work..

Posted (edited)

Well,I use this code in my server now and it works just fine.
I think it's necessary to add / at the end of the link:
 

http://l2.hopzone.net/lineage2/details/98632/L2-cyrex/

Like there is "/" after l2-cyrex

Edited by StealthyS4m
Posted (edited)

Well,I use this code in my server now and it works just fine.

I think it's necessary to add / at the end of the link:

 

http://l2.hopzone.net/lineage2/details/98632/L2-cyrex/

Like there is "/" after l2-cyrex

if is this the problem i will cry. i will really cry

. still doesnt work xD

Edited by te0x
Posted (edited)
public static void voteHopzone(L2PcInstance player)
    {
        final L2PcInstance player2 = player;
        showVoteHtml(player2);
.
.
.

why not

public static void voteHopzone(final L2PcInstance player)
    {
        showVoteHtml(player);
.
.
.
Edited by Klay
Posted

Are you using my whole code or only some parts of it?

told ya only the part tha reads the hopzone votes.

but i can't get it why it works as a voice command or in the auto reward with this code and not in the npc!

anyways nice share ;d

Posted (edited)

Klay,
Yeah it would work perfectly,just I needed to create final variable,because when calling from inside of ThreadPoolManager you have to call variable of type final.
te0x,
This code is easy to redo for NPC:

        if (actualCommand.startsWith("command"))
        VotingReward.showVoteHtml(activeChar);


This would be a bit of waste if you don't want  /vote command at all,but I think it should work.

Edited by StealthyS4m
Posted

te0x i can't belive this, you can't fix hopzone problem on individual manager?

use this , for me working fine :) w/o any problem.

 

protected static int getVotes()
{
InputStreamReader isr = null;
BufferedReader br = null;

try
{
if(!hopzoneUrl.endsWith(".html"))
hopzoneUrl+=".html";

URLConnection con = new URL(hopzoneUrl).openConnection();


con.addRequestProperty("User-L2Hopzone", "Mozilla/4.76");
isr = new InputStreamReader(con.getInputStream());
br = new BufferedReader(isr);

String line;
while ((line = br.readLine()) != null)
{
if (line.contains("no steal make love")||line.contains("no votes here")||line.contains("bang, you don't have votes")|| line.contains("la vita e bella"))
{
int votes = Integer.valueOf(line.split(">")[2].replace("</span", ""));

return votes;
}
}

br.close();
isr.close();
}
catch (Exception e)
{
System.out.println("[VoteRewardManager]: Problem occured while getting Hopzone votes. Error Trace: " + e.getMessage());
}
return -1;
}
Posted

 

te0x i can't belive this, you can't fix hopzone problem on individual manager?

use this , for me working fine :) w/o any problem.

protected static int getVotes()
{
InputStreamReader isr = null;
BufferedReader br = null;

try
{
if(!hopzoneUrl.endsWith(".html"))
hopzoneUrl+=".html";

URLConnection con = new URL(hopzoneUrl).openConnection();


con.addRequestProperty("User-L2Hopzone", "Mozilla/4.76");
isr = new InputStreamReader(con.getInputStream());
br = new BufferedReader(isr);

String line;
while ((line = br.readLine()) != null)
{
if (line.contains("no steal make love")||line.contains("no votes here")||line.contains("bang, you don't have votes")|| line.contains("la vita e bella"))
{
int votes = Integer.valueOf(line.split(">")[2].replace("</span", ""));

return votes;
}
}

br.close();
isr.close();
}
catch (Exception e)
{
System.out.println("[VoteRewardManager]: Problem occured while getting Hopzone votes. Error Trace: " + e.getMessage());
}
return -1;
}

i am trying every day this fcking part and it doesnt work for me in the individual vote manager its impossible.

Posted

its 3 stupid lines

if(!hopzoneUrl.endsWith(".html"))
hopzoneUrl+=".html";

 

and

 

con.addRequestProperty("User-L2Hopzone", "Mozilla/4.76");

 

and how to catch the votes is

if (line.contains("no steal make love")||line.contains("no votes here")||line.contains("bang, you don't have votes")|| line.contains("la vita e bella"))

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
Reply to this topic...

×   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

    • [Release] Solo PvP Zone System 🔹 Compatible with: aCis 401+ 📜 Features: ✅ Automatic Exit on Restart: Players are removed from the zone if a restart occurs or logout. ✅ Custom Exit Command: Players can exit the Solo Zone with the voice command .exit. ✅ Teleport NPC Command: new bypass solopvp for gatekeeper. ✅ Random Name Generator: Generates random names. ✅ PvP Flag: The players are flagged within this zone.   xml preview & java code backup code -> https://pastebin.com/974V2p2p   SoloZone.xml <?xml version="1.0" encoding="UTF-8"?> <list> <zone shape="NPoly" minZ="-5200" maxZ="-4680"><!-- Frintezza Solo Zone --> <stat name="name" val="Solo PvP Zone" /> <stat name="locs" val="174244,-89089,-5112;174260,-86881,-5112;173184,-88090,-5112;175309,-88018,-5112;174231,-88019,-5112;175136,-88828,-5104;174962,-87025,-5104;173149,-87142,-5104;173470,-88908,-5112" /> <stat name="restrictedClasses" val="15,16,97" /> <node x="172031" y="-90127"/> <node x="176428" y="-90089"/> <node x="176428" y="-74051"/> <node x="172057" y="-74108"/> </zone> </list> SoloZone Code: diff --git a/java/net/sf/l2j/gameserver/taskmanager/SoloZoneTaskManager.java b/java/net/sf/l2j/gameserver/taskmanager/SoloZoneTaskManager.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/taskmanager/SoloZoneTaskManager.java @@ -0,0 +1,98 @@ +package net.sf.l2j.gameserver.taskmanager; + +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.logging.Logger; + +import net.sf.l2j.commons.random.Rnd; + +import net.sf.l2j.gameserver.data.manager.ZoneManager; +import net.sf.l2j.gameserver.enums.ZoneId; +import net.sf.l2j.gameserver.handler.voicecommandhandlers.VoiceExitSoloZone; +import net.sf.l2j.gameserver.model.World; +import net.sf.l2j.gameserver.model.actor.Player; +import net.sf.l2j.gameserver.model.location.Location; +import net.sf.l2j.gameserver.model.zone.type.SoloZone; + + +/** + * @author MarGaZeaS + */ +public class SoloZoneTaskManager implements Runnable { + + private static final Location EXIT_LOCATION = VoiceExitSoloZone.getExitLocation(); // Λαμβάνουμε την έξοδο από το VoiceExitSoloZone + + @Override + public void run() + { + // Διασχίζουμε όλους τους παίκτες του κόσμου + for (Player player : World.getInstance().getPlayers()) + { + // Ελέγχουμε αν ο παίκτης είναι στο SoloZone + if (player.isInsideZone(ZoneId.SOLO)) + { + // Μεταφέρουμε τον παίκτη στην έξοδο + player.teleportTo(EXIT_LOCATION.getX(), EXIT_LOCATION.getY(), EXIT_LOCATION.getZ(), 0); + player.sendMessage("The server is restarting, you have been moved out of the Solo Zone."); + } + } + } + + private int _id; + + private static final Logger _log = Logger.getLogger(SoloZoneTaskManager.class.getName()); + private static final ArrayList<String> _rndNames = new ArrayList<>(); + private static final int RANDOM_NAMES = 500; + private static final String CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + private int _playersInSoloZone = 0; + + public int getPlayersInside() { + return _playersInSoloZone; + } + + public void setPlayersInside(int val) { + _playersInSoloZone = val; + } + + public SoloZoneTaskManager() { + _log.info("Solo Zone System: Loading..."); + for (int i = 0; i < RANDOM_NAMES; i++) { + String name = generateName(); + _rndNames.add(name); + _log.info("Generated name: " + name); + } + _log.info("Solo Zone System: Loaded " + _rndNames.size() + " names."); + } + + public String getAName() { + if (_rndNames.isEmpty()) { + _log.warning("SoloZoneManager: No random names available."); + return "Unknown"; + } + return _rndNames.get(Rnd.get(5, RANDOM_NAMES - 5)); + } + + private static String generateName() { + SecureRandom rnd = new SecureRandom(); + StringBuilder sb = new StringBuilder(15); + for (int i = 0; i < 15; i++) { + sb.append(CHARS.charAt(rnd.nextInt(CHARS.length()))); + } + return sb.toString(); + } + + public int getZoneId() + { + return _id; + } + + public final static SoloZone getCurrentZone() { + return ZoneManager.getInstance().getAllZones(SoloZone.class) + .stream() + .findFirst() // Επιστρέφει την πρώτη SoloZone (αν υπάρχει μόνο μία) + .orElse(null); + } + + public static SoloZoneTaskManager getInstance() { + return SingletonHolder._instance; + } + + private static class SingletonHolder { + private static final SoloZoneTaskManager _instance = new SoloZoneTaskManager(); + } +} diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/taskmanager/PvpFlagTaskManager.java b/aCis_gameserver/java/net/sf/l2j/gameserver/taskmanager/PvpFlagTaskManager.java index a707ce5..d247e2e 100644 --- a/aCis_gameserver/java/net/sf/l2j/gameserver/taskmanager/PvpFlagTaskManager.java final Player player = entry.getKey(); final long timeLeft = entry.getValue(); + if(player.isInsideZone(ZoneId.SOLO)) + continue; if(player.isInsideZone(ZoneId.BOSS)) continue; // Time is running out, clear PvP flag and remove from list. if (currentTime > timeLeft) diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestCharacterCreate.java b/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestCharacterCreate.java index a707ce5..d247e2e 100644 +++ b/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestCharacterCreate.java if (Config.ALLOW_FISH_CHAMPIONSHIP) FishingChampionshipManager.getInstance(); + if (Config.ENABLE_STARTUP) + StartupManager.getInstance(); diff --git a/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminMaintenance.java b/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminMaintenance.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminMaintenance.java if (!st.hasMoreTokens()) { sendHtmlForm(player); return; } try { switch (st.nextToken()) { case "shutdown": + SoloZoneTaskManager exitTask = new SoloZoneTaskManager(); + ThreadPool.schedule(exitTask, 0); Shutdown.getInstance().startShutdown(player, null, Integer.parseInt(st.nextToken()), false); break; case "restart": + exitTask = new SoloZoneTaskManager(); + ThreadPool.schedule(exitTask, 0); Shutdown.getInstance().startShutdown(player, null, Integer.parseInt(st.nextToken()), true); break; case "abort": Shutdown.getInstance().abort(player); break; diff --git a/java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoiceExitSoloZone.java b/java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoiceExitSoloZone.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoiceExitSoloZone.java +package net.sf.l2j.gameserver.handler.voicecommandhandlers; + +import net.sf.l2j.commons.pool.ThreadPool; + +import net.sf.l2j.gameserver.enums.ZoneId; +import net.sf.l2j.gameserver.handler.IVoiceCommandHandler; +import net.sf.l2j.gameserver.model.actor.Player; +import net.sf.l2j.gameserver.model.location.Location; +import net.sf.l2j.gameserver.network.serverpackets.MagicSkillUse; + +/** + * Handles the voice command for exiting the Solo Zone with delay and effects. + * + * @author MarGaZeaS + */ +public class VoiceExitSoloZone implements IVoiceCommandHandler +{ + private static final String[] VOICE_COMMANDS = + { + "exit" + }; + + // Default location to teleport players when exiting the Solo Zone + private static final Location EXIT_LOCATION = new Location(81318, 148064, -3464); // Replace with your desired coordinates + + // Προσθήκη της μεθόδου για να πάρουμε την τοποθεσία εξόδου + public static Location getExitLocation() { + return EXIT_LOCATION; + } + + @Override + public void useVoiceCommand(Player player, String command) + { + if (command.equalsIgnoreCase("exit")) + { + if (!player.isInsideZone(ZoneId.SOLO)) + { + player.sendMessage("You are not inside the Solo Zone."); + return; + } + + // Notify the player about the delay + player.sendMessage("You will be teleported out of the Solo Zone in 2 seconds."); + + // Cast skill effect (Skill ID: 2100, Level: 1) + player.broadcastPacket(new MagicSkillUse(player, player, 2100, 1, 2000, 0)); + + // Schedule the teleportation after a 2-second delay + ThreadPool.schedule(() -> { + // Teleport the player to the designated exit location + player.teleportTo(EXIT_LOCATION.getX(), EXIT_LOCATION.getY(), EXIT_LOCATION.getZ(), 0); + + // Inform the player + player.sendMessage("You have exited the Solo Zone."); + }, 2000); // Delay in milliseconds (2000ms = 2 seconds) + } + } + + @Override + public String[] getVoiceCommandList() + { + return VOICE_COMMANDS; + } +} diff --git a/java/net/sf/l2j/gameserver/handler/VoiceCommandHandler.java b/java/net/sf/l2j/gameserver/handler/VoiceCommandHandler.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/handler/VoiceCommandHandler.java public class VoiceCommandHandler { private final Map<String, IVoiceCommandHandler> _entries = new HashMap<>(); protected VoiceCommandHandler() { ............ ............ + registerHandler(new VoiceExitSoloZone()); } public void registerHandler(IVoiceCommandHandler handler) { for (String command : handler.getVoiceCommandList()) _entries.put(command, handler); } diff --git a/java/net/sf/l2j/gameserver/model/actor/Npc.java b/java/net/sf/l2j/gameserver/model/actor/Npc.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/model/actor/Npc.java else if (command.startsWith("Chat")) { int val = 0; try { val = Integer.parseInt(command.substring(5)); } catch (final IndexOutOfBoundsException ioobe) { } catch (final NumberFormatException nfe) { } showChatWindow(player, val); + ) + else if (command.startsWith("solopvp")) + { + SoloZoneTaskManager.getInstance(); + player.teleportTo(SoloZoneTaskManager.getCurrentZone().getLoc(), 25); + } else if (command.startsWith("Link")) { final String path = command.substring(5).trim(); if (path.indexOf("..") != -1) return; final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId()); html.setFile("data/html/" + path); html.replace("%objectId%", getObjectId()); player.sendPacket(html); } diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java b/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java // Fixed. - else if (_requestType == 4) - { - if (!player.isGM() && !player.isFestivalParticipant()) - return; - - loc = player.getPosition(); - } + if (_requestType == 4) + { + // Έλεγχος αν ο παίκτης δεν είναι GM, δεν είναι μέρος του φεστιβάλ και δεν είναι στην Solo Zone + if (!player.isGM() && !player.isFestivalParticipant() && !player.isInsideZone(ZoneId.SOLO)) + { + return; + } + + SoloZoneTaskManager.getInstance(); + SoloZone currentZone = SoloZoneTaskManager.getCurrentZone(); + if (currentZone != null && currentZone.getLoc() != null) + { + // Αν υπάρχει ζώνη και οι τοποθεσίες δεν είναι κενές, χρησιμοποιούμε τυχαία τοποθεσία από την ζώνη + loc = currentZone.getLoc(); + } else + { + // Διαφορετικά, κάνουμε respawn στην τρέχουσα θέση του παίκτη + loc = player.getPosition(); + } + } diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java b/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java if (player.isFestivalParticipant() && FestivalOfDarknessManager.getInstance().isFestivalInitialized()) { player.sendPacket(SystemMessageId.NO_RESTART_HERE); sendPacket(RestartResponse.valueOf(false)); return; } + if (player.isInsideZone(ZoneId.SOLO)) + { + player.sendMessage("You cannot restart your character while in Solo Zone. Use .exit to leave"); + player.setFakeName(null); + sendPacket(RestartResponse.valueOf(false)); + return; + } player.removeFromBossZone(); diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java b/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java player.removeFromBossZone(); player.logout(true); } } + + if (player.isInsideZone(ZoneId.SOLO)) + { + player.sendMessage("You cannot logout or restart your character while in Solo Zone. Use .exit to leave"); + player.setFakeName(null); + player.sendPacket(ActionFailed.STATIC_PACKET); + return; + } + player.removeFromBossZone(); player.logout(true); } } diff --git a/java/net/sf/l2j/gameserver/model/zone/type/SoloZone.java b/java/net/sf/l2j/gameserver/model/zone/type/SoloZone.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/model/zone/type/SoloZone.java +package net.sf.l2j.gameserver.model.zone.type; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import net.sf.l2j.commons.random.Rnd; + +import net.sf.l2j.Config; +import net.sf.l2j.gameserver.enums.MessageType; +import net.sf.l2j.gameserver.enums.ZoneId; +import net.sf.l2j.gameserver.handler.voicecommandhandlers.VoiceExitSoloZone; +import net.sf.l2j.gameserver.model.World; +import net.sf.l2j.gameserver.model.actor.Creature; +import net.sf.l2j.gameserver.model.actor.Player; +import net.sf.l2j.gameserver.model.location.Location; +import net.sf.l2j.gameserver.model.zone.type.subtype.ZoneType; +import net.sf.l2j.gameserver.network.SystemMessageId; +import net.sf.l2j.gameserver.network.serverpackets.EtcStatusUpdate; +import net.sf.l2j.gameserver.taskmanager.PvpFlagTaskManager; +import net.sf.l2j.gameserver.taskmanager.SoloZoneTaskManager; + +/** + * @author MarGaZeaS + * + */ +public class SoloZone extends ZoneType +{ + private String _name; + private List<Location> _locations = new ArrayList<>(); + + public SoloZone(int id) + { + super(id); + } + + @Override + public void setParameter(String name, String value) + { + if (name.equals("name")) + _name = value; + else if (name.equals("locs")) + { + for (String locs : value.split(";")) + { + String[] coordinates = locs.split(","); + if (coordinates.length == 3) + { + int x = Integer.parseInt(coordinates[0]); + int y = Integer.parseInt(coordinates[1]); + int z = Integer.parseInt(coordinates[2]); + _locations.add(new Location(x, y, z)); + } + else + { + LOGGER.warn("Invalid location format: " + locs); + } + } + } + } + + + @Override + protected void onEnter(Creature character) + { + if (character instanceof Player) + { + final Player player = (Player) character; + + if ((player.getClassId().getId() == 15 || player.getClassId().getId() == 16 || player.getClassId().getId() == 97)) + { + Location respawnLocation = VoiceExitSoloZone.getExitLocation(); + player.instantTeleportTo(respawnLocation, 20); + player.sendMessage("Your class is not allowed in this zone."); + return; + } + + String randomName = SoloZoneTaskManager.getInstance().getAName(); + if (randomName == null || randomName.isEmpty() || !isValidName(randomName)) + { + randomName = generateRandomName(); + } + if (isNameAlreadyTaken(randomName)) + { + randomName = generateRandomName(); + } + player.setFakeName(randomName); + player.sendMessage("Welcome to the Solo Zone, your random name is: " + randomName); + player.sendPacket(SystemMessageId.ENTERED_COMBAT_ZONE); + character.setInsideZone(ZoneId.SOLO, true); + character.setInsideZone(ZoneId.NO_STORE, true); + character.setInsideZone(ZoneId.NO_SUMMON_FRIEND, true); + + if (player.getParty() != null) + { + player.getParty().removePartyMember(player, MessageType.DISCONNECTED); + } + + if (player.getPvpFlag() > 0) + PvpFlagTaskManager.getInstance().remove(player, true); + + player.updatePvPStatus(); + player.broadcastUserInfo(); + } + } + + private static boolean isValidName(String name) { + return name.matches("[a-zA-Z0-9_]+"); + } + + private static String generateRandomName() { + Random rand = new Random(); + int nameLength = rand.nextInt(12) + 4; + StringBuilder nameBuilder = new StringBuilder(); + + for (int i = 0; i < nameLength; i++) { + char randomChar = (char) (rand.nextInt(26) + 'a'); + nameBuilder.append(randomChar); + } + + return nameBuilder.toString(); + } + + private static boolean isNameAlreadyTaken(String name) { + return World.getInstance().getPlayers().stream().anyMatch(player -> player.getFakeName().equals(name)); + } + + @Override + protected void onExit(Creature character) + { + character.setInsideZone(ZoneId.SOLO, false); // Solo zone + character.setInsideZone(ZoneId.NO_STORE, false); // Allow making a store + character.setInsideZone(ZoneId.NO_SUMMON_FRIEND, false); // Allow summon + + if (character instanceof Player) + { + final Player player = (Player) character; + + if (player.getFakeName() != null) + { + player.setFakeName(null); + } + + player.sendPacket(SystemMessageId.LEFT_COMBAT_ZONE); + { + if(!player.isInObserverMode() && player.getPvpFlag() > 0) + PvpFlagTaskManager.getInstance().add(player, Config.PVP_NORMAL_TIME); + + player.sendPacket(new EtcStatusUpdate(player)); + player.broadcastUserInfo(); + } + } + } + + public String getName() + { + return _name; + } + + public Location getLoc() + { + if (_locations.isEmpty()) + { + return null; // Αν η λίστα είναι κενή, επιστρέφουμε null + } + return _locations.get(Rnd.get(0, _locations.size() - 1)); // Επιλέγουμε τυχαία τοποθεσία + } +} diff --git a/java/net/sf/l2j/gameserver/GameServer.java b/java/net/sf/l2j/gameserver/GameServer.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/GameServer.java if (Config.ALLOW_FISH_CHAMPIONSHIP) FishingChampionshipManager.getInstance(); + StringUtil.printSection("Custom Features"); + SoloZoneTaskManager.getInstance(); StringUtil.printSection("Handlers"); LOGGER.info("Loaded {} admin command handlers.", AdminCommandHandler.getInstance().size()); diff --git a/java/net/sf/l2j/gameserver/GameServer.java b/java/net/sf/l2j/gameserver/Shutdown.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/Shutdown.java // disconnect players try { disconnectAllPlayers(); LOGGER.info("All players have been disconnected."); } catch (Exception e) { // Silent catch. } + // Restore real names for players in SoloZone + restoreRealNamesInSoloZone(); // stop all threadpolls ThreadPool.shutdown(); try { LoginServerThread.getInstance().interrupt(); } catch (Exception e) { // Silent catch. } // avoids new players from logging in if (_secondsShut <= 60 && LoginServerThread.getInstance().getServerType() != ServerType.DOWN) LoginServerThread.getInstance().setServerType(ServerType.DOWN); _secondsShut--; Thread.sleep(1000); } } catch (InterruptedException e) { } } + // This method restores the real names of players in SoloZone + private static void restoreRealNamesInSoloZone() + { + for (Player player : World.getInstance().getPlayers()) + { + // Check if player is inside the SoloZone + if (player.isInsideZone(ZoneId.SOLO)) + { + // Restore the real name by removing the fake name + if (player.getFakeName() != null) + { + player.setFakeName(null); // Restore the real name + LOGGER.info("Player {}'s fake name has been removed and real name restored.", player.getName()); + } + } + } + } private static void sendServerQuit(int seconds) { World.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_SERVER_WILL_BE_COMING_DOWN_IN_S1_SECONDS).addNumber(seconds)); } diff --git a/java/net/sf/l2j/gameserver/enums/ZoneId.java b/java/net/sf/l2j/gameserver/enums/ZoneId.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/enums/ZoneId.java public enum ZoneId { PVP(0), PEACE(1), SIEGE(2), MOTHER_TREE(3), CLAN_HALL(4), NO_LANDING(5), WATER(6), JAIL(7), MONSTER_TRACK(8), CASTLE(9), SWAMP(10), NO_SUMMON_FRIEND(11), NO_STORE(12), TOWN(13), HQ(14), DANGER_AREA(15), CAST_ON_ARTIFACT(16), NO_RESTART(17), SCRIPT(18), - BOSS(19), + BOSS(19), + SOLO(20); private final int _id; private ZoneId(int id) { _id = id; } diff --git a/java/net/sf/l2j/gameserver/network/serverpackets/Die.java b/java/net/sf/l2j/gameserver/network/serverpackets/Die.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/network/serverpackets/Die.java if (creature instanceof Player) { Player player = (Player) creature; - _allowFixedRes = player.getAccessLevel().allowFixedRes(); + _allowFixedRes = player.getAccessLevel().allowFixedRes() || player.isInsideZone(ZoneId.SOLO); _clan = player.getClan(); } diff --git a/java/net/sf/l2j/gameserver/model/actor/Player.java b/java/net/sf/l2j/gameserver//model/actor/Player.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java // Attacker or spectator logging into a siege zone will be ported at town. if (player.isInsideZone(ZoneId.SIEGE) && player.getSiegeState() < 2) player.teleportTo(TeleportType.TOWN); + if (player.isInsideZone(ZoneId.SOLO)) + { + ThreadPool.schedule(() -> { + Location exitLocation = VoiceExitSoloZone.getExitLocation(); + + if (exitLocation != null) + { + player.teleportTo(exitLocation.getX(), exitLocation.getY(), exitLocation.getZ(), 0); + player.sendMessage("You have been moved to the exit of the SoloZone."); + } + }, 5000); // 5000 milliseconds (5sec) + } diff --git a/java/net/sf/l2j/gameserver/model/actor/Player.java b/java/net/sf/l2j/gameserver/model/actor/Player.java new file mode 100644 index 0000000..6b7ef6f --- /dev/null +++ a/java/net/sf/l2j/gameserver/model/actor/Player.java @Override public void doRevive() { super.doRevive(); stopEffects(EffectType.CHARM_OF_COURAGE); sendPacket(new EtcStatusUpdate(this)); getStatus().setCpHpMp(getStatus().getMaxCp(), getStatus().getMaxHp(), getStatus().getMaxMp()); _reviveRequested = 0; _revivePower = 0; if (isMounted()) startFeed(_mountNpcId); + if (isInsideZone(ZoneId.SOLO)) + { + // Give Nobless (1323 ID) + L2Skill no = SkillTable.getInstance().getInfo(1323, 1); + no.getEffects(this, this); + sendMessage("You have received the Nobless status in the Solo Zone."); + } + }   If anyone thinks the code is wrong, please make an update and upload it here so I can update the post. A part was edited with chatgpt
    • Always remember, when you buy files, just compare with my files that I publish for free. and you will know that you are being ripped off. Greetings to all community!!! 🙂
    • Thank you for sharing. You are a capable and skilled person. Thank you again for your selfless dedication, Guytis🫡
    • he kept his promise! i think it's a good idea to unban his old account. he shares files with the community and could help both new and veteran l2off users! good job, Guytis!
  • Topics

×
×
  • Create New...