Noticias:

No tienes permiso para ver los enlaces. Para poder verlos Registrate o Conectate.

Menú Principal

Hopzone/topzone/network Vote Reward

Iniciado por Swarlog, Ago 03, 2025, 12:26 AM

Tema anterior - Siguiente tema

Swarlog

### Eclipse Workspace Patch 1.0
#P L2J_Mobius
Index: java/com/l2jserver/gameserver/votereward/Network.java
===================================================================
--- java/com/l2jserver/gameserver/votereward/Network.java	(revision 0)
+++ java/com/l2jserver/gameserver/votereward/Network.java	(working copy)
@@ -0,0 +1,81 @@
+/*
+ * 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.votereward;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Map;
+
+import com.l2jserver.Config;
+
+/**
+ * @author Anarchy
+ */
+public class Network extends VoteSystem
+{
+	public Network(int votesDiff, boolean allowReport, int boxes, Map<Integer, Integer> rewards, int checkMins)
+	{
+		super(votesDiff, allowReport, boxes, rewards, checkMins);
+	}
+	
+	@Override
+	public void run()
+	{
+		reward();
+	}
+	
+	@Override
+	public int getVotes()
+	{
+		InputStreamReader isr = null;
+		BufferedReader br = null;
+		
+		try
+		{
+			URLConnection con = new URL(Config.NETWORK_SERVER_LINK).openConnection();
+			con.addRequestProperty("User-L2Network", "Mozilla/4.76");
+			isr = new InputStreamReader(con.getInputStream());
+			br = new BufferedReader(isr);
+			
+			String line;
+			while ((line = br.readLine()) != null)
+			{
+				if (line.contains("<div class=\"tls-in-sts\"><b style"))
+				{
+					int votes = Integer.valueOf(line.split(">")[2].replace("</b", ""));
+					return votes;
+				}
+			}
+			
+			br.close();
+			isr.close();
+		}
+		catch (Exception e)
+		{
+			e.printStackTrace();
+			System.out.println("Error while getting server vote count from " + getSiteName() + ".");
+		}
+		
+		return -1;
+	}
+	
+	@Override
+	public String getSiteName()
+	{
+		return "Network";
+	}
+}
Index: java/com/l2jserver/gameserver/votereward/Hopzone.java
===================================================================
--- java/com/l2jserver/gameserver/votereward/Hopzone.java	(revision 0)
+++ java/com/l2jserver/gameserver/votereward/Hopzone.java	(working copy)
@@ -0,0 +1,81 @@
+/*
+ * 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.votereward;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Map;
+
+import com.l2jserver.Config;
+
+/**
+ * @author Anarchy
+ */
+public class Hopzone extends VoteSystem
+{
+	public Hopzone(int votesDiff, boolean allowReport, int boxes, Map<Integer, Integer> rewards, int checkMins)
+	{
+		super(votesDiff, allowReport, boxes, rewards, checkMins);
+	}
+	
+	@Override
+	public void run()
+	{
+		reward();
+	}
+	
+	@Override
+	public int getVotes()
+	{
+		InputStreamReader isr = null;
+		BufferedReader br = null;
+		
+		try
+		{
+			URLConnection con = new URL(Config.HOPZONE_SERVER_LINK).openConnection();
+			con.addRequestProperty("User-Agent", "Mozilla/4.76");
+			isr = new InputStreamReader(con.getInputStream());
+			br = new BufferedReader(isr);
+			
+			String line;
+			while ((line = br.readLine()) != null)
+			{
+				if (line.contains("<li><span class=\"rank anonymous tooltip\" title"))
+				{
+					int votes = Integer.valueOf(line.split(">")[2].replace("</span", ""));
+					return votes;
+				}
+			}
+			
+			br.close();
+			isr.close();
+		}
+		catch (Exception e)
+		{
+			e.printStackTrace();
+			System.out.println("Error while getting server vote count from " + getSiteName() + ".");
+		}
+		
+		return -1;
+	}
+	
+	@Override
+	public String getSiteName()
+	{
+		return "Hopzone";
+	}
+}
Index: java/com/l2jserver/gameserver/votereward/Network.java
===================================================================
--- java/com/l2jserver/gameserver/votereward/Network.java	(revision 0)
+++ java/com/l2jserver/gameserver/votereward/Network.java	(working copy)
@@ -0,0 +1,81 @@
+/*
+ * 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.votereward;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Map;
+
+import com.l2jserver.Config;
+
+/**
+ * @author Anarchy
+ */
+public class Network extends VoteSystem
+{
+	public Network(int votesDiff, boolean allowReport, int boxes, Map<Integer, Integer> rewards, int checkMins)
+	{
+		super(votesDiff, allowReport, boxes, rewards, checkMins);
+	}
+	
+	@Override
+	public void run()
+	{
+		reward();
+	}
+	
+	@Override
+	public int getVotes()
+	{
+		InputStreamReader isr = null;
+		BufferedReader br = null;
+		
+		try
+		{
+			URLConnection con = new URL(Config.NETWORK_SERVER_LINK).openConnection();
+			con.addRequestProperty("User-L2Network", "Mozilla/4.76");
+			isr = new InputStreamReader(con.getInputStream());
+			br = new BufferedReader(isr);
+			
+			String line;
+			while ((line = br.readLine()) != null)
+			{
+				if (line.contains("<div class=\"tls-in-sts\"><b style"))
+				{
+					int votes = Integer.valueOf(line.split(">")[2].replace("</b", ""));
+					return votes;
+				}
+			}
+			
+			br.close();
+			isr.close();
+		}
+		catch (Exception e)
+		{
+			e.printStackTrace();
+			System.out.println("Error while getting server vote count from " + getSiteName() + ".");
+		}
+		
+		return -1;
+	}
+	
+	@Override
+	public String getSiteName()
+	{
+		return "Network";
+	}
+}
Index: java/com/l2jserver/gameserver/votereward/Topzone.java
===================================================================
--- java/com/l2jserver/gameserver/votereward/Topzone.java	(revision 0)
+++ java/com/l2jserver/gameserver/votereward/Topzone.java	(working copy)
@@ -0,0 +1,81 @@
+/*
+ * 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.votereward;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Map;
+
+import com.l2jserver.Config;
+
+/**
+ * @author Anarchy
+ */
+public class Topzone extends VoteSystem
+{
+	public Topzone(int votesDiff, boolean allowReport, int boxes, Map<Integer, Integer> rewards, int checkMins)
+	{
+		super(votesDiff, allowReport, boxes, rewards, checkMins);
+	}
+	
+	@Override
+	public void run()
+	{
+		reward();
+	}
+	
+	@Override
+	public int getVotes()
+	{
+		InputStreamReader isr = null;
+		BufferedReader br = null;
+		
+		try
+		{
+			URLConnection con = new URL(Config.TOPZONE_SERVER_LINK).openConnection();
+			con.addRequestProperty("User-Agent", "L2TopZone");
+			isr = new InputStreamReader(con.getInputStream());
+			br = new BufferedReader(isr);
+			
+			String line;
+			while ((line = br.readLine()) != null)
+			{
+				if (line.contains("</span></small>"))
+				{
+					int votes = Integer.valueOf(line.split(">")[9].replace("</span", ""));
+					return votes;
+				}
+			}
+			
+			br.close();
+			isr.close();
+		}
+		catch (Exception e)
+		{
+			e.printStackTrace();
+			System.out.println("Error while getting server vote count from " + getSiteName() + ".");
+		}
+		
+		return -1;
+	}
+	
+	@Override
+	public String getSiteName()
+	{
+		return "Topzone";
+	}
+}
Index: java/com/l2jserver/gameserver/votereward/VoteSystem.java
===================================================================
--- java/com/l2jserver/gameserver/votereward/VoteSystem.java	(revision 0)
+++ java/com/l2jserver/gameserver/votereward/VoteSystem.java	(working copy)
@@ -0,0 +1,182 @@
+/*
+ * 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.votereward;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.ChatType;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author Anarchy
+ */
+public abstract class VoteSystem implements Runnable
+{
+	private static List<VoteSystem> voteSystems = new ArrayList<>();
+	
+	protected int votesDiff;
+	protected boolean allowReport;
+	protected int boxes;
+	protected Map<Integer, Integer> rewards;
+	protected int checkMins;
+	protected int lastVotes = 0;
+	private final Map<String, Integer> playerIps = new HashMap<>();
+	
+	public static void initialize()
+	{
+		System.out.println("Vote System: Loaded");
+		if (Config.ALLOW_NETWORK_VOTE_REWARD)
+		{
+			voteSystems.add(new Network(Config.NETWORK_VOTES_DIFFERENCE, Config.ALLOW_NETWORK_GAME_SERVER_REPORT, Config.NETWORK_DUALBOXES_ALLOWED, Config.NETWORK_REWARD, Config.NETWORK_REWARD_CHECK_TIME));
+		}
+		if (Config.ALLOW_TOPZONE_VOTE_REWARD)
+		{
+			voteSystems.add(new Topzone(Config.TOPZONE_VOTES_DIFFERENCE, Config.ALLOW_TOPZONE_GAME_SERVER_REPORT, Config.TOPZONE_DUALBOXES_ALLOWED, Config.TOPZONE_REWARD, Config.TOPZONE_REWARD_CHECK_TIME));
+		}
+		if (Config.ALLOW_HOPZONE_VOTE_REWARD)
+		{
+			voteSystems.add(new Hopzone(Config.HOPZONE_VOTES_DIFFERENCE, Config.ALLOW_HOPZONE_GAME_SERVER_REPORT, Config.HOPZONE_DUALBOXES_ALLOWED, Config.HOPZONE_REWARD, Config.HOPZONE_REWARD_CHECK_TIME));
+		}
+	}
+	
+	public static VoteSystem getVoteSystem(String name)
+	{
+		for (VoteSystem vs : voteSystems)
+		{
+			if (vs.getSiteName().equals(name))
+			{
+				return vs;
+			}
+		}
+		
+		return null;
+	}
+	
+	public VoteSystem(int votesDiff, boolean allowReport, int boxes, Map<Integer, Integer> rewards, int checkMins)
+	{
+		this.votesDiff = votesDiff;
+		this.allowReport = allowReport;
+		this.boxes = boxes;
+		this.rewards = rewards;
+		this.checkMins = checkMins;
+		
+		ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(this, checkMins * 1000 * 60, checkMins * 1000 * 60);
+	}
+	
+	protected void reward()
+	{
+		int currentVotes = getVotes();
+		
+		if (currentVotes == -1)
+		{
+			System.out.println("There was a problem on getting server votes.");
+			return;
+		}
+		
+		if (lastVotes == 0)
+		{
+			lastVotes = currentVotes;
+			announce(getSiteName() + ": Current vote count is " + currentVotes + ".");
+			announce(getSiteName() + ": We need " + ((lastVotes + votesDiff) - currentVotes) + " vote(s) for reward.");
+			if (allowReport)
+			{
+				System.out.println("Server votes on " + getSiteName() + ": " + currentVotes);
+				System.out.println("Votes needed for reward: " + ((lastVotes + votesDiff) - currentVotes));
+			}
+			return;
+		}
+		
+		if (currentVotes >= (lastVotes + votesDiff))
+		{
+			Collection<L2PcInstance> pls = L2World.getInstance().getPlayers();
+			if (allowReport)
+			{
+				System.out.println("Server votes on " + getSiteName() + ": " + currentVotes);
+				System.out.println("Votes needed for next reward: " + ((currentVotes + votesDiff) - currentVotes));
+			}
+			announce(getSiteName() + ": Everyone has been rewarded.");
+			announce(getSiteName() + ": Current vote count is " + currentVotes + ".");
+			announce(getSiteName() + ": We need " + votesDiff + " vote(s) for next reward.");
+			for (L2PcInstance p : pls)
+			{
+				if ((p.getClient() == null) || p.getClient().isDetached())
+				{
+					continue;
+				}
+				
+				boolean canReward = false;
+				String pIp = p.getClient().getConnection().getInetAddress().getHostAddress();
+				if (playerIps.containsKey(pIp))
+				{
+					int count = playerIps.get(pIp);
+					if (count < boxes)
+					{
+						playerIps.remove(pIp);
+						playerIps.put(pIp, count + 1);
+						canReward = true;
+					}
+				}
+				else
+				{
+					canReward = true;
+					playerIps.put(pIp, 1);
+				}
+				if (canReward)
+				{
+					for (int i : rewards.keySet())
+					{
+						p.addItem("Vote reward.", i, rewards.get(i), p, true);
+					}
+				}
+				else
+				{
+					p.sendMessage("Already " + boxes + " character(s) of your ip have been rewarded, so this character won't be rewarded.");
+				}
+			}
+			playerIps.clear();
+			
+			lastVotes = currentVotes;
+		}
+		else
+		{
+			if (allowReport)
+			{
+				System.out.println("Server votes on " + getSiteName() + ": " + currentVotes);
+				System.out.println("Votes needed for next reward: " + ((lastVotes + votesDiff) - currentVotes));
+			}
+			announce(getSiteName() + ": Current vote count is " + currentVotes + ".");
+			announce(getSiteName() + ": We need " + ((lastVotes + votesDiff) - currentVotes) + " vote(s) for reward.");
+		}
+	}
+	
+	private static void announce(String msg)
+	{
+		CreatureSay cs = new CreatureSay(0, ChatType.NPC_GENERAL, "", msg);
+		Broadcast.toAllOnlinePlayers(cs);
+	}
+	
+	public abstract int getVotes();
+	
+	public abstract String getSiteName();
+}
\ No newline at end of file
Index: java/com/l2jserver/gameserver/GameServer.java
===================================================================
--- java/com/l2jserver/gameserver/GameServer.java	(revision 1053)
+++ java/com/l2jserver/gameserver/GameServer.java	(working copy)
@@ -150,6 +150,7 @@
 import com.l2jserver.gameserver.scripting.L2ScriptEngineManager;
 import com.l2jserver.gameserver.taskmanager.KnownListUpdateTaskManager;
 import com.l2jserver.gameserver.taskmanager.TaskManager;
+import com.l2jserver.gameserver.votereward.VoteSystem;
 import com.l2jserver.status.Status;
 import com.l2jserver.util.DeadLockDetector;
 import com.l2jserver.util.IPv4Filter;
@@ -385,6 +386,9 @@
 			FishingChampionshipManager.getInstance();
 		}
 		
+		printSection("Vote Reward");
+		VoteSystem.initialize();
+		
 		TaskManager.getInstance();
 		
 		AntiFeedManager.getInstance().registerEvent(AntiFeedManager.GAME_ID);
Index: dist/game/config/Custom.ini
===================================================================
--- dist/game/config/Custom.ini	(revision 1052)
+++ dist/game/config/Custom.ini	(working copy)
@@ -752,3 +752,64 @@
 # Used when RewardLowExpKills is enabled.
 # Default 50 (%)
 RewardLowExpKillsChance = 50
+
+# ---------------------------------------------------------------------------
+# Vote reward System
+# ---------------------------------------------------------------------------
+
+# Vote reward for Network.
+AllowNetworkVoteReward = False
+# Vote reward server link. (IMPORTANT!!!! Always add .html at the end of the link)
+NetworkServerLink = 
+# Votes for next reward needed.
+NetworkVotesDifference = 4
+# Minutes between rewards.
+# Eg. You put 5 it checks every 5 minutes for reward.
+NetworkRewardCheckTime = 5
+# Reward(s).
+NetworkReward = 3481,5;
+# Network reward max dual boxes reward.
+# For example if you put 2 and someone has 3 boxes open 2 will be rewarded.
+NetworkDuaboxesAllowed = 1
+# Game server console report.
+# If set to true, game server console will get a report of
+# current vote count, votes needed for next reward and votes needed for first page.
+AllowNetworkGameServerReport = False
+
+# Vote reward for Topzone.
+AllowTopzoneVoteReward = False
+# Vote reward server link. (IMPORTANT!!!! Always add .html at the end of the link)
+TopzoneServerLink = 
+# Votes for next reward needed.
+TopzoneVotesDifference = 4
+# Minutes between rewards.
+# Eg. You put 5 it checks every 5 minutes for reward.
+TopzoneRewardCheckTime = 5
+# Reward(s).
+TopzoneReward = 3481,5;
+# Topzone reward max dual boxes reward.
+# For example if you put 2 and someone has 3 boxes open 2 will be rewarded.
+TopzoneDuaboxesAllowed = 1
+# Game server console report.
+# If set to true, game server console will get a report of
+# current vote count, votes needed for next reward and votes needed for first page.
+AllowTopzoneGameServerReport = False
+
+# Vote reward for Hopzone.
+AllowHopzoneVoteReward = False
+# Vote reward server link. (IMPORTANT!!!! Always add .html at the end of the link)
+HopzoneServerLink = 
+# Votes for next reward needed.
+HopzoneVotesDifference = 4
+# Minutes between rewards.
+# Eg. You put 5 it checks every 5 minutes for reward.
+HopzoneRewardCheckTime = 5
+# Reward(s).
+HopzoneReward = 3481,5;
+# Topzone reward max dual boxes reward.
+# For example if you put 2 and someone has 3 boxes open 2 will be rewarded.
+HopzoneDuaboxesAllowed = 1
+# Game server console report.
+# If set to true, game server console will get a report of
+# current vote count, votes needed for next reward and votes needed for first page.
+AllowHopzoneGameServerReport = False
\ No newline at end of file
Index: java/com/l2jserver/Config.java
===================================================================
--- java/com/l2jserver/Config.java	(revision 1052)
+++ java/com/l2jserver/Config.java	(working copy)
@@ -845,6 +845,27 @@
 	public static boolean PC_BANG_RANDOM_POINT;
 	public static boolean PC_BANG_REWARD_LOW_EXP_KILLS;
 	public static int PC_BANG_LOW_EXP_KILLS_CHANCE;
+	public static boolean ALLOW_NETWORK_VOTE_REWARD;
+	public static String NETWORK_SERVER_LINK;
+	public static int NETWORK_VOTES_DIFFERENCE;
+	public static int NETWORK_REWARD_CHECK_TIME;
+	public static Map<Integer, Integer> NETWORK_REWARD = new HashMap<>();
+	public static int NETWORK_DUALBOXES_ALLOWED;
+	public static boolean ALLOW_NETWORK_GAME_SERVER_REPORT;
+	public static boolean ALLOW_TOPZONE_VOTE_REWARD;
+	public static String TOPZONE_SERVER_LINK;
+	public static int TOPZONE_VOTES_DIFFERENCE;
+	public static int TOPZONE_REWARD_CHECK_TIME;
+	public static Map<Integer, Integer> TOPZONE_REWARD = new HashMap<>();
+	public static int TOPZONE_DUALBOXES_ALLOWED;
+	public static boolean ALLOW_TOPZONE_GAME_SERVER_REPORT;
+	public static boolean ALLOW_HOPZONE_VOTE_REWARD;
+	public static String HOPZONE_SERVER_LINK;
+	public static int HOPZONE_VOTES_DIFFERENCE;
+	public static int HOPZONE_REWARD_CHECK_TIME;
+	public static Map<Integer, Integer> HOPZONE_REWARD = new HashMap<>();
+	public static int HOPZONE_DUALBOXES_ALLOWED;
+	public static boolean ALLOW_HOPZONE_GAME_SERVER_REPORT;
 	
 	// --------------------------------------------------
 	// NPC Settings
@@ -2703,6 +2724,45 @@
 			{
 				PC_BANG_LOW_EXP_KILLS_CHANCE = 100;
 			}
+			ALLOW_NETWORK_VOTE_REWARD = CustomSettings.getBoolean("AllowNetworkVoteReward", false);
+			NETWORK_SERVER_LINK = CustomSettings.getString("NetworkServerLink", "");
+			NETWORK_VOTES_DIFFERENCE = CustomSettings.getInt("NetworkVotesDifference", 5);
+			NETWORK_REWARD_CHECK_TIME = CustomSettings.getInt("NetworkRewardCheckTime", 5);
+			String NETWORK_SMALL_REWARD_VALUE = CustomSettings.getString("NetworkReward", "57,100000000;");
+			String[] NETWORK_small_reward_splitted_1 = NETWORK_SMALL_REWARD_VALUE.split(";");
+			for (String i : NETWORK_small_reward_splitted_1)
+			{
+				String[] NETWORK_small_reward_splitted_2 = i.split(",");
+				NETWORK_REWARD.put(Integer.parseInt(NETWORK_small_reward_splitted_2[0]), Integer.parseInt(NETWORK_small_reward_splitted_2[1]));
+			}
+			NETWORK_DUALBOXES_ALLOWED = CustomSettings.getInt("NetworkDualboxesAllowed", 1);
+			ALLOW_NETWORK_GAME_SERVER_REPORT = CustomSettings.getBoolean("AllowNetworkGameServerReport", false);
+			ALLOW_TOPZONE_VOTE_REWARD = CustomSettings.getBoolean("AllowTopzoneVoteReward", false);
+			TOPZONE_SERVER_LINK = CustomSettings.getString("TopzoneServerLink", "");
+			TOPZONE_VOTES_DIFFERENCE = CustomSettings.getInt("TopzoneVotesDifference", 5);
+			TOPZONE_REWARD_CHECK_TIME = CustomSettings.getInt("TopzoneRewardCheckTime", 5);
+			String TOPZONE_SMALL_REWARD_VALUE = CustomSettings.getString("TopzoneReward", "57,100000000;");
+			String[] topzone_small_reward_splitted_1 = TOPZONE_SMALL_REWARD_VALUE.split(";");
+			for (String i : topzone_small_reward_splitted_1)
+			{
+				String[] topzone_small_reward_splitted_2 = i.split(",");
+				TOPZONE_REWARD.put(Integer.parseInt(topzone_small_reward_splitted_2[0]), Integer.parseInt(topzone_small_reward_splitted_2[1]));
+			}
+			TOPZONE_DUALBOXES_ALLOWED = CustomSettings.getInt("TopzoneDualboxesAllowed", 1);
+			ALLOW_TOPZONE_GAME_SERVER_REPORT = CustomSettings.getBoolean("AllowTopzoneGameServerReport", false);
+			ALLOW_HOPZONE_VOTE_REWARD = CustomSettings.getBoolean("AllowHopzoneVoteReward", false);
+			HOPZONE_SERVER_LINK = CustomSettings.getString("HopzoneServerLink", "");
+			HOPZONE_VOTES_DIFFERENCE = CustomSettings.getInt("HopzoneVotesDifference", 5);
+			HOPZONE_REWARD_CHECK_TIME = CustomSettings.getInt("HopzoneRewardCheckTime", 5);
+			String HOPZONE_SMALL_REWARD_VALUE = CustomSettings.getString("HopzoneReward", "57,100000000;");
+			String[] hopzone_small_reward_splitted_1 = HOPZONE_SMALL_REWARD_VALUE.split(";");
+			for (String i : hopzone_small_reward_splitted_1)
+			{
+				String[] hopzone_small_reward_splitted_2 = i.split(",");
+				HOPZONE_REWARD.put(Integer.parseInt(hopzone_small_reward_splitted_2[0]), Integer.parseInt(hopzone_small_reward_splitted_2[1]));
+			}
+			HOPZONE_DUALBOXES_ALLOWED = CustomSettings.getInt("HopzoneDualboxesAllowed", 1);
+			ALLOW_HOPZONE_GAME_SERVER_REPORT = CustomSettings.getBoolean("AllowHopzoneGameServerReport", false);
 			
 			// Load PvP L2Properties file (if exists)
 			final PropertiesParser PVPSettings = new PropertiesParser(PVP_CONFIG_FILE);
Index: java/com/l2jserver/gameserver/votereward/Topzone.java
===================================================================
--- java/com/l2jserver/gameserver/votereward/Topzone.java	(revision 0)
+++ java/com/l2jserver/gameserver/votereward/Topzone.java	(working copy)
@@ -0,0 +1,81 @@
+/*
+ * 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.votereward;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Map;
+
+import com.l2jserver.Config;
+
+/**
+ * @author Anarchy
+ */
+public class Topzone extends VoteSystem
+{
+	public Topzone(int votesDiff, boolean allowReport, int boxes, Map<Integer, Integer> rewards, int checkMins)
+	{
+		super(votesDiff, allowReport, boxes, rewards, checkMins);
+	}
+	
+	@Override
+	public void run()
+	{
+		reward();
+	}
+	
+	@Override
+	public int getVotes()
+	{
+		InputStreamReader isr = null;
+		BufferedReader br = null;
+		
+		try
+		{
+			URLConnection con = new URL(Config.TOPZONE_SERVER_LINK).openConnection();
+			con.addRequestProperty("User-Agent", "L2TopZone");
+			isr = new InputStreamReader(con.getInputStream());
+			br = new BufferedReader(isr);
+			
+			String line;
+			while ((line = br.readLine()) != null)
+			{
+				if (line.contains("</span></small>"))
+				{
+					int votes = Integer.valueOf(line.split(">")[9].replace("</span", ""));
+					return votes;
+				}
+			}
+			
+			br.close();
+			isr.close();
+		}
+		catch (Exception e)
+		{
+			e.printStackTrace();
+			System.out.println("Error while getting server vote count from " + getSiteName() + ".");
+		}
+		
+		return -1;
+	}
+	
+	@Override
+	public String getSiteName()
+	{
+		return "Topzone";
+	}
+}
Index: java/com/l2jserver/gameserver/votereward/VoteSystem.java
===================================================================
--- java/com/l2jserver/gameserver/votereward/VoteSystem.java	(revision 0)
+++ java/com/l2jserver/gameserver/votereward/VoteSystem.java	(working copy)
@@ -0,0 +1,182 @@
+/*
+ * 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.votereward;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.ChatType;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author Anarchy
+ */
+public abstract class VoteSystem implements Runnable
+{
+	private static List<VoteSystem> voteSystems = new ArrayList<>();
+	
+	protected int votesDiff;
+	protected boolean allowReport;
+	protected int boxes;
+	protected Map<Integer, Integer> rewards;
+	protected int checkMins;
+	protected int lastVotes = 0;
+	private final Map<String, Integer> playerIps = new HashMap<>();
+	
+	public static void initialize()
+	{
+		System.out.println("Vote System: Loaded");
+		if (Config.ALLOW_NETWORK_VOTE_REWARD)
+		{
+			voteSystems.add(new Network(Config.NETWORK_VOTES_DIFFERENCE, Config.ALLOW_NETWORK_GAME_SERVER_REPORT, Config.NETWORK_DUALBOXES_ALLOWED, Config.NETWORK_REWARD, Config.NETWORK_REWARD_CHECK_TIME));
+		}
+		if (Config.ALLOW_TOPZONE_VOTE_REWARD)
+		{
+			voteSystems.add(new Topzone(Config.TOPZONE_VOTES_DIFFERENCE, Config.ALLOW_TOPZONE_GAME_SERVER_REPORT, Config.TOPZONE_DUALBOXES_ALLOWED, Config.TOPZONE_REWARD, Config.TOPZONE_REWARD_CHECK_TIME));
+		}
+		if (Config.ALLOW_HOPZONE_VOTE_REWARD)
+		{
+			voteSystems.add(new Hopzone(Config.HOPZONE_VOTES_DIFFERENCE, Config.ALLOW_HOPZONE_GAME_SERVER_REPORT, Config.HOPZONE_DUALBOXES_ALLOWED, Config.HOPZONE_REWARD, Config.HOPZONE_REWARD_CHECK_TIME));
+		}
+	}
+	
+	public static VoteSystem getVoteSystem(String name)
+	{
+		for (VoteSystem vs : voteSystems)
+		{
+			if (vs.getSiteName().equals(name))
+			{
+				return vs;
+			}
+		}
+		
+		return null;
+	}
+	
+	public VoteSystem(int votesDiff, boolean allowReport, int boxes, Map<Integer, Integer> rewards, int checkMins)
+	{
+		this.votesDiff = votesDiff;
+		this.allowReport = allowReport;
+		this.boxes = boxes;
+		this.rewards = rewards;
+		this.checkMins = checkMins;
+		
+		ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(this, checkMins * 1000 * 60, checkMins * 1000 * 60);
+	}
+	
+	protected void reward()
+	{
+		int currentVotes = getVotes();
+		
+		if (currentVotes == -1)
+		{
+			System.out.println("There was a problem on getting server votes.");
+			return;
+		}
+		
+		if (lastVotes == 0)
+		{
+			lastVotes = currentVotes;
+			announce(getSiteName() + ": Current vote count is " + currentVotes + ".");
+			announce(getSiteName() + ": We need " + ((lastVotes + votesDiff) - currentVotes) + " vote(s) for reward.");
+			if (allowReport)
+			{
+				System.out.println("Server votes on " + getSiteName() + ": " + currentVotes);
+				System.out.println("Votes needed for reward: " + ((lastVotes + votesDiff) - currentVotes));
+			}
+			return;
+		}
+		
+		if (currentVotes >= (lastVotes + votesDiff))
+		{
+			Collection<L2PcInstance> pls = L2World.getInstance().getPlayers();
+			if (allowReport)
+			{
+				System.out.println("Server votes on " + getSiteName() + ": " + currentVotes);
+				System.out.println("Votes needed for next reward: " + ((currentVotes + votesDiff) - currentVotes));
+			}
+			announce(getSiteName() + ": Everyone has been rewarded.");
+			announce(getSiteName() + ": Current vote count is " + currentVotes + ".");
+			announce(getSiteName() + ": We need " + votesDiff + " vote(s) for next reward.");
+			for (L2PcInstance p : pls)
+			{
+				if ((p.getClient() == null) || p.getClient().isDetached())
+				{
+					continue;
+				}
+				
+				boolean canReward = false;
+				String pIp = p.getClient().getConnection().getInetAddress().getHostAddress();
+				if (playerIps.containsKey(pIp))
+				{
+					int count = playerIps.get(pIp);
+					if (count < boxes)
+					{
+						playerIps.remove(pIp);
+						playerIps.put(pIp, count + 1);
+						canReward = true;
+					}
+				}
+				else
+				{
+					canReward = true;
+					playerIps.put(pIp, 1);
+				}
+				if (canReward)
+				{
+					for (int i : rewards.keySet())
+					{
+						p.addItem("Vote reward.", i, rewards.get(i), p, true);
+					}
+				}
+				else
+				{
+					p.sendMessage("Already " + boxes + " character(s) of your ip have been rewarded, so this character won't be rewarded.");
+				}
+			}
+			playerIps.clear();
+			
+			lastVotes = currentVotes;
+		}
+		else
+		{
+			if (allowReport)
+			{
+				System.out.println("Server votes on " + getSiteName() + ": " + currentVotes);
+				System.out.println("Votes needed for next reward: " + ((lastVotes + votesDiff) - currentVotes));
+			}
+			announce(getSiteName() + ": Current vote count is " + currentVotes + ".");
+			announce(getSiteName() + ": We need " + ((lastVotes + votesDiff) - currentVotes) + " vote(s) for reward.");
+		}
+	}
+	
+	private static void announce(String msg)
+	{
+		CreatureSay cs = new CreatureSay(0, ChatType.NPC_GENERAL, "", msg);
+		Broadcast.toAllOnlinePlayers(cs);
+	}
+	
+	public abstract int getVotes();
+	
+	public abstract String getSiteName();
+}
\ No newline at end of file
Index: java/com/l2jserver/gameserver/votereward/Hopzone.java
===================================================================
--- java/com/l2jserver/gameserver/votereward/Hopzone.java	(revision 0)
+++ java/com/l2jserver/gameserver/votereward/Hopzone.java	(working copy)
@@ -0,0 +1,81 @@
+/*
+ * 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.votereward;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Map;
+
+import com.l2jserver.Config;
+
+/**
+ * @author Anarchy
+ */
+public class Hopzone extends VoteSystem
+{
+	public Hopzone(int votesDiff, boolean allowReport, int boxes, Map<Integer, Integer> rewards, int checkMins)
+	{
+		super(votesDiff, allowReport, boxes, rewards, checkMins);
+	}
+	
+	@Override
+	public void run()
+	{
+		reward();
+	}
+	
+	@Override
+	public int getVotes()
+	{
+		InputStreamReader isr = null;
+		BufferedReader br = null;
+		
+		try
+		{
+			URLConnection con = new URL(Config.HOPZONE_SERVER_LINK).openConnection();
+			con.addRequestProperty("User-Agent", "Mozilla/4.76");
+			isr = new InputStreamReader(con.getInputStream());
+			br = new BufferedReader(isr);
+			
+			String line;
+			while ((line = br.readLine()) != null)
+			{
+				if (line.contains("<li><span class=\"rank anonymous tooltip\" title"))
+				{
+					int votes = Integer.valueOf(line.split(">")[2].replace("</span", ""));
+					return votes;
+				}
+			}
+			
+			br.close();
+			isr.close();
+		}
+		catch (Exception e)
+		{
+			e.printStackTrace();
+			System.out.println("Error while getting server vote count from " + getSiteName() + ".");
+		}
+		
+		return -1;
+	}
+	
+	@Override
+	public String getSiteName()
+	{
+		return "Hopzone";
+	}
+}