· 7 years ago · Dec 02, 2018, 03:24 PM
1Index: java/net/sf/l2j/gameserver/votereward/VoteApiService.java
2IDEA additional info:
3Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4<+>UTF-8
5===================================================================
6--- java/net/sf/l2j/gameserver/votereward/VoteApiService.java (date 1543688983838)
7+++ java/net/sf/l2j/gameserver/votereward/VoteApiService.java (date 1543688983838)
8@@ -0,0 +1,50 @@
9+package net.sf.l2j.gameserver.votereward;
10+
11+import java.io.BufferedReader;
12+import java.io.InputStreamReader;
13+import java.net.HttpURLConnection;
14+import java.net.URL;
15+import java.util.logging.Level;
16+import java.util.logging.Logger;
17+
18+public class VoteApiService {
19+ private static final Logger LOGGER = Logger.getLogger(VoteApiService.class.getName());
20+
21+ public static String getApiResponse(String endpoint)
22+ {
23+ StringBuilder stringBuilder = new StringBuilder();
24+
25+ try
26+ {
27+ URL url = new URL(endpoint);
28+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
29+ connection.addRequestProperty("User-Agent", "Mozilla/4.76");
30+ connection.setRequestMethod("GET");
31+
32+ connection.setReadTimeout(5*1000);
33+ connection.connect();
34+
35+ if(connection.getResponseCode() != 200){
36+ LOGGER.log(Level.WARNING, "VoteApiService::getApiResponse returned " + connection.getResponseCode());
37+ connection.disconnect();
38+ return "";
39+ }
40+
41+ try(BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())))
42+ {
43+ String line;
44+ while ((line = reader.readLine()) != null)
45+ {
46+ stringBuilder.append(line).append("\n");
47+ }
48+ }
49+ connection.disconnect();
50+ return stringBuilder.toString();
51+ }
52+ catch (Exception e)
53+ {
54+ LOGGER.log(Level.SEVERE, "Something went wrong in VoteBase::getApiResponse", e);
55+ return "";
56+ }
57+ }
58+}
59Index: java/net/sf/l2j/gameserver/model/actor/instance/Player.java
60IDEA additional info:
61Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
62<+>UTF-8
63===================================================================
64--- java/net/sf/l2j/gameserver/model/actor/instance/Player.java (revision 41ba208a948216d9ac1b6fbe513583d77ae24411)
65+++ java/net/sf/l2j/gameserver/model/actor/instance/Player.java (date 1543687951509)
66@@ -22,6 +22,7 @@
67 import java.util.stream.Collectors;
68
69 import net.sf.l2j.commons.concurrent.ThreadPool;
70+import net.sf.l2j.commons.lang.StringUtil;
71 import net.sf.l2j.commons.math.MathUtil;
72 import net.sf.l2j.commons.random.Rnd;
73
74@@ -240,6 +241,9 @@
75 import net.sf.l2j.gameserver.templates.skills.L2EffectType;
76 import net.sf.l2j.gameserver.templates.skills.L2SkillType;
77 import net.sf.l2j.gameserver.util.Broadcast;
78+import net.sf.l2j.gameserver.votereward.VoteDao;
79+import net.sf.l2j.gameserver.votereward.VoteSite;
80+import net.sf.l2j.gameserver.votereward.VotedRecord;
81
82 /**
83 * This class represents a player in the world.<br>
84@@ -247,7 +251,7 @@
85 */
86 public final class Player extends Playable
87 {
88- public enum StoreType
89+ public enum StoreType
90 {
91 NONE(0),
92 SELL(1),
93@@ -10127,4 +10131,64 @@
94 }
95 }
96 }
97+
98+ private boolean _isVoting;
99+
100+ public boolean isVoting() {
101+ return _isVoting;
102+ }
103+
104+ public void setIsVoting(boolean isVoting){
105+ _isVoting = isVoting;
106+ }
107+
108+ private Map<VoteSite, Long> _lastVoteTimestamps = new HashMap<VoteSite, Long>() {{
109+ put(VoteSite.HOPZONE, -1L);
110+ put(VoteSite.TOPZONE, -1L);
111+ put(VoteSite.NETWORK, -1L);
112+ }};
113+
114+ public long getLastVotedTimestamp(VoteSite voteSite){
115+ return _lastVoteTimestamps.get(voteSite);
116+ }
117+
118+ public void setLastVotedTimestamp(VoteSite voteSite, long timestamp){
119+ _lastVoteTimestamps.put(voteSite, timestamp);
120+ }
121+
122+ public boolean isEligibleToVote(VoteSite voteSite){
123+ if(getLastVotedTimestamp(voteSite) == -1){
124+ return VoteDao.canVoteOnSite(this, voteSite);
125+ }
126+
127+ return (getLastVotedTimestamp(voteSite) + 43200000) < System.currentTimeMillis();
128+ }
129+
130+ public String getVoteCountdown(VoteSite voteSite)
131+ {
132+ if(getLastVotedTimestamp(voteSite) == -1){
133+ if(VoteDao.canVoteOnSite(this, voteSite))
134+ return "You can vote now";
135+ }
136+
137+ long youCanVote = getLastVotedTimestamp(voteSite) - (System.currentTimeMillis() - 43200000);
138+ if(youCanVote <= 0)
139+ return "You can vote now";
140+ return StringUtil.convertLongToCountdown(youCanVote);
141+ }
142+
143+ public String getIpAddress(){
144+ return getClient().getConnection().getInetAddress().getHostAddress();
145+ }
146 }
147\ No newline at end of file
148Index: java/net/sf/l2j/gameserver/votereward/VotedRecord.java
149IDEA additional info:
150Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
151<+>UTF-8
152===================================================================
153--- java/net/sf/l2j/gameserver/votereward/VotedRecord.java (date 1543685402185)
154+++ java/net/sf/l2j/gameserver/votereward/VotedRecord.java (date 1543685402185)
155@@ -0,0 +1,33 @@
156+package net.sf.l2j.gameserver.votereward;
157+
158+public class VotedRecord {
159+
160+ private final String _accountName;
161+ private final String _ipAddress;
162+ private final long _dateTimeVoted;
163+ private final String _voteSiteName;
164+
165+ public VotedRecord(String accountName, String ipAddress, long dateTimeVoted, String voteSiteName) {
166+ _accountName = accountName;
167+ _ipAddress = ipAddress;
168+ _dateTimeVoted = dateTimeVoted;
169+
170+ _voteSiteName = voteSiteName;
171+ }
172+
173+ public long getDateTimeVoted() {
174+ return _dateTimeVoted;
175+ }
176+
177+ public String getIpAddress() {
178+ return _ipAddress;
179+ }
180+
181+ public String getAccountName() {
182+ return _accountName;
183+ }
184+
185+ public String getVoteSiteName() {
186+ return _voteSiteName;
187+ }
188+}
189Index: java/net/sf/l2j/gameserver/votereward/VoteSiteInfo.java
190IDEA additional info:
191Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
192<+>UTF-8
193===================================================================
194--- java/net/sf/l2j/gameserver/votereward/VoteSiteInfo.java (date 1543687132877)
195+++ java/net/sf/l2j/gameserver/votereward/VoteSiteInfo.java (date 1543687132877)
196@@ -0,0 +1,13 @@
197+package net.sf.l2j.gameserver.votereward;
198+
199+import java.lang.annotation.ElementType;
200+import java.lang.annotation.Retention;
201+import java.lang.annotation.RetentionPolicy;
202+import java.lang.annotation.Target;
203+
204+@Retention(RetentionPolicy.RUNTIME)
205+@Target(ElementType.TYPE)
206+public @interface VoteSiteInfo {
207+ VoteSite voteSite();
208+ String apiKey();
209+}
210Index: java/net/sf/l2j/gameserver/votereward/NetworkVoteReward.java
211IDEA additional info:
212Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
213<+>UTF-8
214===================================================================
215--- java/net/sf/l2j/gameserver/votereward/NetworkVoteReward.java (date 1543687373567)
216+++ java/net/sf/l2j/gameserver/votereward/NetworkVoteReward.java (date 1543687373567)
217@@ -0,0 +1,29 @@
218+package net.sf.l2j.gameserver.votereward;
219+
220+import net.sf.l2j.gameserver.model.actor.instance.Player;
221+
222+@VoteSiteInfo(voteSite = VoteSite.NETWORK, apiKey = "NetworkApiKey")
223+public class NetworkVoteReward extends VoteRewardSite {
224+
225+ @Override
226+ protected String getEndpoint(Player player) {
227+ return String.format("https://l2network.eu/index.php?a=in&u=L2BattleRoyale&ipc=%s", player.getIpAddress());
228+ }
229+
230+ @Override
231+ protected boolean hasVoted(Player player) {
232+ String serverResponse = VoteApiService.getApiResponse(getEndpoint(player));
233+
234+ if(serverResponse.length() == 0){
235+ player.sendMessage("Something went wrong with this request. Report it to the administrator.");
236+ return false;
237+ }
238+
239+ try{
240+ return Integer.parseInt(serverResponse.trim()) == 1;
241+ }catch (Exception e){
242+ player.sendMessage("Something went wrong with this request. Report it to the administrator.");
243+ return false;
244+ }
245+ }
246+}
247Index: java/net/sf/l2j/gameserver/votereward/VoteRewardSite.java
248IDEA additional info:
249Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
250<+>UTF-8
251===================================================================
252--- java/net/sf/l2j/gameserver/votereward/VoteRewardSite.java (date 1543689055030)
253+++ java/net/sf/l2j/gameserver/votereward/VoteRewardSite.java (date 1543689055030)
254@@ -0,0 +1,97 @@
255+package net.sf.l2j.gameserver.votereward;
256+
257+import net.sf.l2j.commons.concurrent.ThreadPool;
258+import net.sf.l2j.gameserver.model.World;
259+import net.sf.l2j.gameserver.model.actor.instance.Player;
260+import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
261+
262+import java.util.logging.Level;
263+import java.util.logging.Logger;
264+
265+public abstract class VoteRewardSite {
266+
267+ private static final Logger LOGGER = Logger.getLogger(VoteRewardSite.class.getName());
268+
269+ protected abstract String getEndpoint(Player player);
270+
271+ public void checkVoteReward(Player player){
272+ try
273+ {
274+ if(player.isVoting())
275+ {
276+ player.sendMessage("You are already voting.");
277+ player.sendPacket(ActionFailed.STATIC_PACKET);
278+ return;
279+ }
280+
281+ if(World.getInstance().getPlayers().stream().filter(Player::isVoting).count() >= 5){
282+ player.sendMessage("Many people are voting currently. Try again in a couple of seconds.");
283+ player.sendPacket(ActionFailed.STATIC_PACKET);
284+ return;
285+ }
286+
287+ player.setIsVoting(true);
288+
289+ if(!player.isEligibleToVote(getVoteSiteInfo().voteSite()))
290+ {
291+ player.setIsVoting(false);
292+ player.sendMessage("You can't vote for us yet.");
293+ player.sendPacket(ActionFailed.STATIC_PACKET);
294+ return;
295+ }
296+
297+ ThreadPool.execute(() -> {
298+
299+ try{
300+ if(!hasVoted(player)){
301+ player.setIsVoting(false);
302+ player.sendMessage(String.format("You haven't voted yet. Head to %s and vote for us.", getVoteSiteInfo().voteSite().getName()));
303+ player.sendPacket(ActionFailed.STATIC_PACKET);
304+ return;
305+ }
306+
307+ long dateTimevoted = System.currentTimeMillis();
308+
309+ VotedRecord votedRecord = new VotedRecord(player.getAccountName(), player.getIpAddress(), dateTimevoted, getVoteSiteInfo().voteSite().getName());
310+
311+ VoteDao.addVotedRecord(votedRecord);
312+ player.setLastVotedTimestamp(getVoteSiteInfo().voteSite(), dateTimevoted);
313+ reward(player);
314+ player.setIsVoting(false);
315+ }catch (Exception e){
316+ handleExceptionForVoteAttempt(player, e);
317+ }
318+
319+ });
320+
321+ }catch (Exception e){
322+ handleExceptionForVoteAttempt(player, e);
323+ }
324+ }
325+
326+ protected abstract boolean hasVoted(Player player);
327+
328+ protected void reward(Player player){
329+ player.sendMessage("Thanks for voting! Here's your reward.");
330+ player.addAdena("votereward", 5000, null,true);
331+ }
332+
333+ private VoteSiteInfo getVoteSiteInfo() {
334+ return getClass().getAnnotation(VoteSiteInfo.class);
335+ }
336+
337+ String getApiKey(){
338+ return getVoteSiteInfo().apiKey();
339+ }
340+
341+ private void handleExceptionForVoteAttempt(Player player, Exception e) {
342+ player.setIsVoting(false);
343+ player.sendPacket(ActionFailed.STATIC_PACKET);
344+ LOGGER.log(Level.WARNING, "There was an error during a vote attempt", e);
345+ }
346+
347+ @Override
348+ public String toString() {
349+ return getClass().getAnnotation(VoteSiteInfo.class).voteSite().getName();
350+ }
351+}
352Index: java/net/sf/l2j/gameserver/votereward/TopzoneVoteReward.java
353IDEA additional info:
354Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
355<+>UTF-8
356===================================================================
357--- java/net/sf/l2j/gameserver/votereward/TopzoneVoteReward.java (date 1543687498629)
358+++ java/net/sf/l2j/gameserver/votereward/TopzoneVoteReward.java (date 1543687498629)
359@@ -0,0 +1,32 @@
360+package net.sf.l2j.gameserver.votereward;
361+
362+import com.google.gson.*;
363+import net.sf.l2j.gameserver.model.actor.instance.Player;
364+
365+@VoteSiteInfo(voteSite = VoteSite.TOPZONE, apiKey = "TopzoneApiKey")
366+public class TopzoneVoteReward extends VoteRewardSite {
367+
368+ @Override
369+ protected String getEndpoint(Player player) {
370+ return String.format("https://api.l2topzone.com/v1/vote?token=%s&ip=%s", getApiKey(), player.getIpAddress());
371+ }
372+
373+ @Override
374+ protected boolean hasVoted(Player player) {
375+ String serverResponse = VoteApiService.getApiResponse(getEndpoint(player));
376+ if(serverResponse.length() == 0){
377+ player.sendMessage("Something went wrong with this request. Report it to the administrator.");
378+ return false;
379+ }
380+ JsonElement jelement = new JsonParser().parse(serverResponse);
381+ JsonObject topObject = jelement.getAsJsonObject();
382+ JsonPrimitive isOkPrimitive = topObject.getAsJsonPrimitive("ok");
383+ if(!isOkPrimitive.getAsBoolean()){
384+ return false;
385+ }
386+
387+ JsonObject votedObject = topObject.getAsJsonObject("result");
388+ JsonPrimitive isVotedObject = votedObject.getAsJsonPrimitive("isVoted");
389+ return isVotedObject.getAsBoolean();
390+ }
391+}
392Index: java/net/sf/l2j/gameserver/handler/IVoicedCommandHandler.java
393IDEA additional info:
394Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
395<+>UTF-8
396===================================================================
397--- java/net/sf/l2j/gameserver/handler/IVoicedCommandHandler.java (date 1543688336103)
398+++ java/net/sf/l2j/gameserver/handler/IVoicedCommandHandler.java (date 1543688336103)
399@@ -0,0 +1,8 @@
400+package net.sf.l2j.gameserver.handler;
401+
402+import net.sf.l2j.gameserver.model.actor.instance.Player;
403+
404+public interface IVoicedCommandHandler {
405+ void useVoicedCommand(Player activeChar);
406+ String[] getVoicedCommands();
407+}
408Index: java/net/sf/l2j/gameserver/votereward/HopzoneVoteReward.java
409IDEA additional info:
410Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
411<+>UTF-8
412===================================================================
413--- java/net/sf/l2j/gameserver/votereward/HopzoneVoteReward.java (date 1543689067047)
414+++ java/net/sf/l2j/gameserver/votereward/HopzoneVoteReward.java (date 1543689067047)
415@@ -0,0 +1,29 @@
416+package net.sf.l2j.gameserver.votereward;
417+
418+import com.google.gson.JsonElement;
419+import com.google.gson.JsonObject;
420+import com.google.gson.JsonParser;
421+import com.google.gson.JsonPrimitive;
422+import net.sf.l2j.gameserver.model.actor.instance.Player;
423+
424+@VoteSiteInfo(voteSite = VoteSite.HOPZONE, apiKey = "HopzoneApiKey")
425+public class HopzoneVoteReward extends VoteRewardSite {
426+
427+ @Override
428+ protected String getEndpoint(Player player) {
429+ return String.format("https://api.hopzone.net/lineage2/vote?token=%s&ip_address=%s", getApiKey(), player.getIpAddress());
430+ }
431+
432+ @Override
433+ protected boolean hasVoted(Player player) {
434+ String serverResponse = VoteApiService.getApiResponse(getEndpoint(player));
435+ if(serverResponse.length() == 0){
436+ player.sendMessage("Something went wrong with this request. Report it to the administrator.");
437+ return false;
438+ }
439+ JsonElement jelement = new JsonParser().parse(serverResponse);
440+ JsonObject topObject = jelement.getAsJsonObject();
441+ JsonPrimitive votedObject = topObject.getAsJsonPrimitive("voted");
442+ return votedObject.getAsBoolean();
443+ }
444+}
445Index: java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java
446IDEA additional info:
447Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
448<+>UTF-8
449===================================================================
450--- java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java (date 1543688706143)
451+++ java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java (date 1543688706143)
452@@ -0,0 +1,46 @@
453+package net.sf.l2j.gameserver.handler;
454+
455+import net.sf.l2j.gameserver.handler.voicecommandhandlers.VoteHopzoneCommandHandler;
456+import net.sf.l2j.gameserver.handler.voicecommandhandlers.VoteNetworkCommandHandler;
457+import net.sf.l2j.gameserver.handler.voicecommandhandlers.VoteTopzoneCommandHandler;
458+
459+import java.util.Arrays;
460+import java.util.HashMap;
461+import java.util.Map;
462+
463+public final class VoicedCommandHandler
464+{
465+ private static final Map<Integer, IVoicedCommandHandler> VOICED_COMMANDS = new HashMap<>();
466+
467+ private VoicedCommandHandler()
468+ {
469+ registerVoicedCommand(new VoteHopzoneCommandHandler());
470+ registerVoicedCommand(new VoteTopzoneCommandHandler());
471+ registerVoicedCommand(new VoteNetworkCommandHandler());
472+ }
473+
474+ private void registerVoicedCommand(IVoicedCommandHandler voicedCommand)
475+ {
476+ Arrays.stream(voicedCommand.getVoicedCommands()).forEach(v -> VOICED_COMMANDS.put(v.intern().hashCode(), voicedCommand));
477+ }
478+
479+ public IVoicedCommandHandler getVoicedCommand(String voicedCommand)
480+ {
481+ return VOICED_COMMANDS.get(voicedCommand.hashCode());
482+ }
483+
484+ public int size()
485+ {
486+ return VOICED_COMMANDS.size();
487+ }
488+
489+ public static final VoicedCommandHandler getInstance()
490+ {
491+ return SingletonHolder.INSTANCE;
492+ }
493+
494+ private static final class SingletonHolder
495+ {
496+ private static final VoicedCommandHandler INSTANCE = new VoicedCommandHandler();
497+ }
498+}
499\ No newline at end of file
500Index: java/net/sf/l2j/gameserver/handler/chathandlers/ChatAll.java
501IDEA additional info:
502Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
503<+>UTF-8
504===================================================================
505--- java/net/sf/l2j/gameserver/handler/chathandlers/ChatAll.java (revision 41ba208a948216d9ac1b6fbe513583d77ae24411)
506+++ java/net/sf/l2j/gameserver/handler/chathandlers/ChatAll.java (date 1543688775219)
507@@ -1,6 +1,8 @@
508 package net.sf.l2j.gameserver.handler.chathandlers;
509
510 import net.sf.l2j.gameserver.handler.IChatHandler;
511+import net.sf.l2j.gameserver.handler.IVoicedCommandHandler;
512+import net.sf.l2j.gameserver.handler.VoicedCommandHandler;
513 import net.sf.l2j.gameserver.model.BlockList;
514 import net.sf.l2j.gameserver.model.actor.instance.Player;
515 import net.sf.l2j.gameserver.network.FloodProtectors;
516@@ -19,6 +21,14 @@
517 {
518 if (!FloodProtectors.performAction(activeChar.getClient(), Action.GLOBAL_CHAT))
519 return;
520+
521+ if (text.startsWith(".")){
522+ final IVoicedCommandHandler voicedCommand = VoicedCommandHandler.getInstance().getVoicedCommand(text.substring(1).toLowerCase());
523+ if (voicedCommand != null){
524+ voicedCommand.useVoicedCommand(activeChar);
525+ return;
526+ }
527+ }
528
529 final CreatureSay cs = new CreatureSay(activeChar.getObjectId(), type, activeChar.getName(), text);
530 for (Player player : activeChar.getKnownTypeInRadius(Player.class, 1250))
531Index: java/net/sf/l2j/commons/lang/StringUtil.java
532IDEA additional info:
533Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
534<+>UTF-8
535===================================================================
536--- java/net/sf/l2j/commons/lang/StringUtil.java (revision 41ba208a948216d9ac1b6fbe513583d77ae24411)
537+++ java/net/sf/l2j/commons/lang/StringUtil.java (date 1543687942252)
538@@ -5,6 +5,7 @@
539 import java.util.Collections;
540 import java.util.List;
541 import java.util.Locale;
542+import java.util.concurrent.TimeUnit;
543 import java.util.logging.Logger;
544 import java.util.regex.Matcher;
545 import java.util.regex.Pattern;
546@@ -171,6 +172,15 @@
547
548 return result;
549 }
550+
551+ public static String convertLongToCountdown(long timestamp)
552+ {
553+ long hours = TimeUnit.MILLISECONDS.toHours(timestamp);
554+ long minutes = TimeUnit.MILLISECONDS.toMinutes(timestamp) -
555+ TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(timestamp));
556+
557+ return hours > 0 ? hours + " hour(s)" : minutes + " minutes(s)";
558+ }
559
560 /**
561 * Format a {@link String} to delete its extension ("castles.xml" > "castles"), if any.
562Index: java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoteTopzoneCommandHandler.java
563IDEA additional info:
564Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
565<+>UTF-8
566===================================================================
567--- java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoteTopzoneCommandHandler.java (date 1543688659582)
568+++ java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoteTopzoneCommandHandler.java (date 1543688659582)
569@@ -0,0 +1,28 @@
570+package net.sf.l2j.gameserver.handler.voicecommandhandlers;
571+
572+import net.sf.l2j.gameserver.handler.IVoicedCommandHandler;
573+import net.sf.l2j.gameserver.model.actor.instance.Player;
574+import net.sf.l2j.gameserver.votereward.TopzoneVoteReward;
575+import net.sf.l2j.gameserver.votereward.VoteSite;
576+
577+public class VoteTopzoneCommandHandler implements IVoicedCommandHandler
578+{
579+ private static final String[] VOICED_COMMANDS = {"votetop"};
580+
581+ @Override
582+ public void useVoicedCommand(Player activeChar)
583+ {
584+ if(activeChar.isEligibleToVote(VoteSite.TOPZONE)){
585+ TopzoneVoteReward rewardSite = new TopzoneVoteReward();
586+ rewardSite.checkVoteReward(activeChar);
587+ return;
588+ }
589+ activeChar.sendMessage("Available in " + activeChar.getVoteCountdown(VoteSite.TOPZONE));
590+ }
591+
592+ @Override
593+ public String[] getVoicedCommands()
594+ {
595+ return VOICED_COMMANDS;
596+ }
597+}
598\ No newline at end of file
599Index: java/net/sf/l2j/gameserver/GameServer.java
600IDEA additional info:
601Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
602<+>UTF-8
603===================================================================
604--- java/net/sf/l2j/gameserver/GameServer.java (revision 41ba208a948216d9ac1b6fbe513583d77ae24411)
605+++ java/net/sf/l2j/gameserver/GameServer.java (date 1542553128220)
606@@ -62,11 +62,7 @@
607 import net.sf.l2j.gameserver.data.xml.TeleportLocationData;
608 import net.sf.l2j.gameserver.data.xml.WalkerRouteData;
609 import net.sf.l2j.gameserver.geoengine.GeoEngine;
610-import net.sf.l2j.gameserver.handler.AdminCommandHandler;
611-import net.sf.l2j.gameserver.handler.ChatHandler;
612-import net.sf.l2j.gameserver.handler.ItemHandler;
613-import net.sf.l2j.gameserver.handler.SkillHandler;
614-import net.sf.l2j.gameserver.handler.UserCommandHandler;
615+import net.sf.l2j.gameserver.handler.*;
616 import net.sf.l2j.gameserver.idfactory.IdFactory;
617 import net.sf.l2j.gameserver.instancemanager.AuctionManager;
618 import net.sf.l2j.gameserver.instancemanager.AutoSpawnManager;
619@@ -277,6 +273,7 @@
620 LOGGER.info("Loaded {} item handlers.", ItemHandler.getInstance().size());
621 LOGGER.info("Loaded {} skill handlers.", SkillHandler.getInstance().size());
622 LOGGER.info("Loaded {} user command handlers.", UserCommandHandler.getInstance().size());
623+ LOGGER.info("Loaded {} vote command handlers.", VoicedCommandHandler.getInstance().size());
624
625 StringUtil.printSection("System");
626 Runtime.getRuntime().addShutdownHook(Shutdown.getInstance());
627Index: java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoteNetworkCommandHandler.java
628IDEA additional info:
629Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
630<+>UTF-8
631===================================================================
632--- java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoteNetworkCommandHandler.java (date 1543688666756)
633+++ java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoteNetworkCommandHandler.java (date 1543688666756)
634@@ -0,0 +1,28 @@
635+package net.sf.l2j.gameserver.handler.voicecommandhandlers;
636+
637+import net.sf.l2j.gameserver.handler.IVoicedCommandHandler;
638+import net.sf.l2j.gameserver.model.actor.instance.Player;
639+import net.sf.l2j.gameserver.votereward.NetworkVoteReward;
640+import net.sf.l2j.gameserver.votereward.VoteSite;
641+
642+public class VoteNetworkCommandHandler implements IVoicedCommandHandler
643+{
644+ private static final String[] VOICED_COMMANDS = {"votenet"};
645+
646+ @Override
647+ public void useVoicedCommand(Player activeChar)
648+ {
649+ if(activeChar.isEligibleToVote(VoteSite.NETWORK)){
650+ NetworkVoteReward rewardSite = new NetworkVoteReward();
651+ rewardSite.checkVoteReward(activeChar);
652+ return;
653+ }
654+ activeChar.sendMessage("Available in " + activeChar.getVoteCountdown(VoteSite.NETWORK));
655+ }
656+
657+ @Override
658+ public String[] getVoicedCommands()
659+ {
660+ return VOICED_COMMANDS;
661+ }
662+}
663\ No newline at end of file
664Index: java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoteHopzoneCommandHandler.java
665IDEA additional info:
666Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
667<+>UTF-8
668===================================================================
669--- java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoteHopzoneCommandHandler.java (date 1543688674182)
670+++ java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoteHopzoneCommandHandler.java (date 1543688674182)
671@@ -0,0 +1,28 @@
672+package net.sf.l2j.gameserver.handler.voicecommandhandlers;
673+
674+import net.sf.l2j.gameserver.handler.IVoicedCommandHandler;
675+import net.sf.l2j.gameserver.model.actor.instance.Player;
676+import net.sf.l2j.gameserver.votereward.HopzoneVoteReward;
677+import net.sf.l2j.gameserver.votereward.VoteSite;
678+
679+public class VoteHopzoneCommandHandler implements IVoicedCommandHandler
680+{
681+ private static final String[] VOICED_COMMANDS = {"votehop"};
682+
683+ @Override
684+ public void useVoicedCommand(Player activeChar)
685+ {
686+ if(activeChar.isEligibleToVote(VoteSite.HOPZONE)){
687+ HopzoneVoteReward rewardSite = new HopzoneVoteReward();
688+ rewardSite.checkVoteReward(activeChar);
689+ return;
690+ }
691+ activeChar.sendMessage("Available in " + activeChar.getVoteCountdown(VoteSite.HOPZONE));
692+ }
693+
694+ @Override
695+ public String[] getVoicedCommands()
696+ {
697+ return VOICED_COMMANDS;
698+ }
699+}
700\ No newline at end of file
701Index: java/net/sf/l2j/gameserver/votereward/VoteSite.java
702IDEA additional info:
703Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
704<+>UTF-8
705===================================================================
706--- java/net/sf/l2j/gameserver/votereward/VoteSite.java (date 1543686071235)
707+++ java/net/sf/l2j/gameserver/votereward/VoteSite.java (date 1543686071235)
708@@ -0,0 +1,19 @@
709+package net.sf.l2j.gameserver.votereward;
710+
711+public enum VoteSite {
712+
713+ HOPZONE("Hopzone"),
714+ TOPZONE("Topzone"),
715+ NETWORK("L2Network");
716+
717+ private final String _name;
718+
719+ VoteSite(String name)
720+ {
721+ _name = name;
722+ }
723+
724+ public String getName(){
725+ return _name;
726+ }
727+}
728Index: java/net/sf/l2j/gameserver/votereward/VoteDao.java
729IDEA additional info:
730Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
731<+>UTF-8
732===================================================================
733--- java/net/sf/l2j/gameserver/votereward/VoteDao.java (date 1543688978311)
734+++ java/net/sf/l2j/gameserver/votereward/VoteDao.java (date 1543688978311)
735@@ -0,0 +1,64 @@
736+package net.sf.l2j.gameserver.votereward;
737+
738+import net.sf.l2j.L2DatabaseFactory;
739+import net.sf.l2j.gameserver.model.actor.instance.Player;
740+
741+import java.sql.Connection;
742+import java.sql.PreparedStatement;
743+import java.sql.ResultSet;
744+import java.sql.SQLException;
745+import java.util.logging.Level;
746+import java.util.logging.Logger;
747+
748+public class VoteDao {
749+
750+ public static final Logger LOGGER = Logger.getLogger(VoteDao.class.getName());
751+
752+ public static void addVotedRecord(VotedRecord votedRecord) {
753+ try (Connection con = L2DatabaseFactory.getInstance().getConnection())
754+ {
755+ PreparedStatement ps = con.prepareStatement("INSERT INTO votedrecords (accountname, ipaddress, datetimevoted, votesitename) VALUES (?,?,?,?);");
756+ ps.setString(1, votedRecord.getAccountName());
757+ ps.setString(2, votedRecord.getIpAddress());
758+ ps.setLong(3, votedRecord.getDateTimeVoted());
759+ ps.setString(4, votedRecord.getVoteSiteName());
760+ ps.execute();
761+ ps.close();
762+ }
763+ catch (SQLException e)
764+ {
765+ LOGGER.log(Level.SEVERE, "Couldn't add voted record", e);
766+ }
767+ }
768+
769+ public static boolean canVoteOnSite(Player player, VoteSite voteSite) {
770+ try (Connection con = L2DatabaseFactory.getInstance().getConnection())
771+ {
772+ PreparedStatement ps = con.prepareStatement("select datetimevoted from votedrecords " +
773+ "where (accountname = ? or ipaddress = ?) and votesitename = ? and datetimevoted + ? > ? " +
774+ "order by datetimevoted " +
775+ "desc limit 1");
776+
777+ ps.setString(1, player.getAccountName());
778+ ps.setString(2, player.getIpAddress());
779+ ps.setString(3, voteSite.getName());
780+ ps.setLong(4, 43200000);
781+ ps.setLong(5, System.currentTimeMillis());
782+ ResultSet rs = ps.executeQuery();
783+
784+ if (!rs.next())
785+ {
786+ return true;
787+ }
788+ player.setLastVotedTimestamp(voteSite, rs.getLong("datetimevoted"));
789+ rs.close();
790+ ps.close();
791+ }
792+ catch (SQLException e)
793+ {
794+ LOGGER.log(Level.SEVERE, "Couldn't check if user can vote", e);
795+ }
796+
797+ return false;
798+ }
799+}
800
801----------------------------
802SQL Table
803
804SET FOREIGN_KEY_CHECKS=0;
805
806DROP TABLE IF EXISTS `votedrecords`;
807CREATE TABLE `votedrecords` (
808 `accountname` varchar(45) NOT NULL,
809 `ipaddress` varchar(100) NOT NULL,
810 `datetimevoted` bigint(20) NOT NULL,
811 `votesitename` varchar(40) NOT NULL
812) ENGINE=InnoDB DEFAULT CHARSET=utf8;