MapleCouponInstaller + EXP/DROP Coupon System
Added mechanics for the EXP/DROP cash coupons (such as enabling out-of-time active coupons via command and automatic update of active ones over the designed interval). Created MapleCouponInstaller as means to gather info about the coupon intervals and rates from the WZs (the generated SQL table is already updated on the db_database.sql file).
This commit is contained in:
@@ -201,7 +201,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private int possibleReports = 10;
|
||||
private int dojoPoints, vanquisherStage, dojoStage, dojoEnergy, vanquisherKills;
|
||||
private int warpToId;
|
||||
private int expRate = 1, mesoRate = 1, dropRate = 1;
|
||||
private int expRate = 1, mesoRate = 1, dropRate = 1, expCoupon = 1, mesoCoupon = 1, dropCoupon = 1;
|
||||
private int omokwins, omokties, omoklosses, matchcardwins, matchcardties, matchcardlosses;
|
||||
private int married;
|
||||
private long dojoFinish, lastfametime, lastUsedCashItem, lastHealed, lastMesoDrop = -1, jailExpiration = -1;
|
||||
@@ -245,6 +245,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private Map<Integer, String> entered = new LinkedHashMap<>();
|
||||
private Set<MapleMapObject> visibleMapObjects = new LinkedHashSet<>();
|
||||
private Map<Skill, SkillEntry> skills = new LinkedHashMap<>();
|
||||
private Map<Integer, Integer> activeCoupons = new LinkedHashMap<>();
|
||||
private Map<Integer, Integer> activeCouponRates = new LinkedHashMap<>();
|
||||
private EnumMap<MapleBuffStat, MapleBuffStatValueHolder> effects = new EnumMap<>(MapleBuffStat.class);
|
||||
private Map<Integer, MapleKeyBinding> keymap = new LinkedHashMap<>();
|
||||
private Map<Integer, MapleSummon> summons = new LinkedHashMap<>();
|
||||
@@ -301,7 +303,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
if (type == MapleInventoryType.CASH) {
|
||||
b = 96;
|
||||
}
|
||||
inventory[type.ordinal()] = new MapleInventory(type, (byte) b);
|
||||
inventory[type.ordinal()] = new MapleInventory(this, type, (byte) b);
|
||||
}
|
||||
for (int i = 0; i < SavedLocationType.values().length; i++) {
|
||||
savedLocations[i] = null;
|
||||
@@ -3269,9 +3271,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
|
||||
this.yellowMessage("We see you reached level " + level + ". Congratulations! As a token of your success, your inventory has been expanded a little bit.");
|
||||
}
|
||||
if (level % 20 == 0 && ServerConstants.USE_ADD_RATES_BY_LEVEL == true) { //For the drop + meso rate
|
||||
revertRates(true);
|
||||
addRates();
|
||||
if (level % 20 == 0 && ServerConstants.USE_ADD_RATES_BY_LEVEL == true) { //For the drop & meso rate
|
||||
revertPlayerRates();
|
||||
setPlayerRates();
|
||||
this.yellowMessage("You managed to get level " + level + "! Getting experience and items seems a little easier now, huh?");
|
||||
}
|
||||
|
||||
@@ -3380,34 +3382,118 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
public void addRates() {
|
||||
public void setPlayerRates() {
|
||||
this.expRate *= EXP_RATE_GAIN[this.level / 20];
|
||||
this.mesoRate *= MESO_RATE_GAIN[this.level / 20];
|
||||
this.dropRate *= DROP_RATE_GAIN[this.level / 20];
|
||||
}
|
||||
|
||||
public void revertRates(boolean lvlup) {
|
||||
if(lvlup == true) {
|
||||
this.expRate /= EXP_RATE_GAIN[(this.level - 1) / 20];
|
||||
this.mesoRate /= MESO_RATE_GAIN[(this.level - 1) / 20];
|
||||
this.dropRate /= DROP_RATE_GAIN[(this.level - 1) / 20];
|
||||
}
|
||||
else {
|
||||
World worldz = Server.getInstance().getWorld(world);
|
||||
|
||||
this.expRate /= worldz.getExpRate();
|
||||
this.mesoRate /= worldz.getMesoRate();
|
||||
this.dropRate /= worldz.getDropRate();
|
||||
}
|
||||
public void revertPlayerRates() {
|
||||
this.expRate /= EXP_RATE_GAIN[(this.level - 1) / 20];
|
||||
this.mesoRate /= MESO_RATE_GAIN[(this.level - 1) / 20];
|
||||
this.dropRate /= DROP_RATE_GAIN[(this.level - 1) / 20];
|
||||
}
|
||||
|
||||
public void setRates() {
|
||||
public void revertWorldRates() {
|
||||
World worldz = Server.getInstance().getWorld(world);
|
||||
|
||||
this.expRate /= worldz.getExpRate();
|
||||
this.mesoRate /= worldz.getMesoRate();
|
||||
this.dropRate /= worldz.getDropRate();
|
||||
}
|
||||
|
||||
public void setWorldRates() {
|
||||
World worldz = Server.getInstance().getWorld(world);
|
||||
|
||||
this.expRate *= worldz.getExpRate();
|
||||
this.mesoRate *= worldz.getMesoRate();
|
||||
this.dropRate *= worldz.getDropRate();
|
||||
}
|
||||
|
||||
public void revertCouponRates() {
|
||||
revertCouponsEffects();
|
||||
}
|
||||
|
||||
public void setCouponRates() {
|
||||
setActiveCoupons();
|
||||
activateCouponsEffects();
|
||||
}
|
||||
|
||||
private boolean isExpCoupon(int couponId) {
|
||||
return couponId / 1000 == 5211;
|
||||
}
|
||||
|
||||
private int getCouponMultiplier(int couponId) {
|
||||
return activeCouponRates.get(couponId);
|
||||
}
|
||||
|
||||
private void setExpCouponRate(int couponId, int couponQty) {
|
||||
this.expCoupon *= (getCouponMultiplier(couponId) * couponQty);
|
||||
}
|
||||
|
||||
private void setDropCouponRate(int couponId, int couponQty) {
|
||||
this.dropCoupon *= (getCouponMultiplier(couponId) * couponQty);
|
||||
this.mesoCoupon *= (getCouponMultiplier(couponId) * couponQty);
|
||||
}
|
||||
|
||||
private void revertCouponsEffects() {
|
||||
this.expRate /= this.expCoupon;
|
||||
this.dropRate /= this.dropCoupon;
|
||||
this.mesoRate /= this.mesoCoupon;
|
||||
|
||||
this.expCoupon = 1;
|
||||
this.dropCoupon = 1;
|
||||
this.mesoCoupon = 1;
|
||||
}
|
||||
|
||||
private void activateCouponsEffects() {
|
||||
if(ServerConstants.USE_STACK_COUPON_RATES) {
|
||||
for(Entry<Integer,Integer> coupon: activeCoupons.entrySet()) {
|
||||
int couponId = coupon.getKey();
|
||||
int couponQty = coupon.getValue();
|
||||
|
||||
if(isExpCoupon(couponId)) setExpCouponRate(couponId, couponQty);
|
||||
else setDropCouponRate(couponId, couponQty);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int maxExpRate = 1, maxDropRate = 1;
|
||||
|
||||
for(Entry<Integer,Integer> coupon: activeCoupons.entrySet()) {
|
||||
int couponId = coupon.getKey();
|
||||
|
||||
if(isExpCoupon(couponId)) maxExpRate = Math.max(maxExpRate, getCouponMultiplier(couponId));
|
||||
else maxDropRate = Math.max(maxDropRate, getCouponMultiplier(couponId));
|
||||
}
|
||||
|
||||
this.expCoupon = maxExpRate;
|
||||
this.dropCoupon = maxDropRate;
|
||||
this.mesoCoupon = maxDropRate;
|
||||
}
|
||||
|
||||
this.expRate *= this.expCoupon;
|
||||
this.dropRate *= this.dropCoupon;
|
||||
this.mesoRate *= this.mesoCoupon;
|
||||
}
|
||||
|
||||
private void setActiveCoupons() {
|
||||
activeCoupons.clear();
|
||||
activeCouponRates.clear();
|
||||
|
||||
Map<Integer, Integer> coupons = Server.getInstance().getCouponRates();
|
||||
List<Integer> active = Server.getInstance().getActiveCoupons();
|
||||
|
||||
for(Item it: this.getInventory(MapleInventoryType.CASH).list()) {
|
||||
if(MapleItemInformationProvider.getInstance().isRateCoupon(it.getItemId()) && active.contains(it.getItemId())) {
|
||||
Integer count = activeCoupons.get(it.getItemId());
|
||||
|
||||
if(count != null) activeCoupons.put(it.getItemId(), count + 1);
|
||||
else {
|
||||
activeCoupons.put(it.getItemId(), 1);
|
||||
activeCouponRates.put(it.getItemId(), coupons.get(it.getItemId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static MapleCharacter loadCharFromDB(int charid, MapleClient client, boolean channelserver) throws SQLException {
|
||||
try {
|
||||
@@ -3732,10 +3818,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
ret.maplemount.setActive(false);
|
||||
|
||||
if(ServerConstants.USE_ADD_RATES_BY_LEVEL == true) {
|
||||
ret.addRates();
|
||||
ret.setPlayerRates();
|
||||
}
|
||||
ret.setRates();
|
||||
|
||||
|
||||
ret.setWorldRates();
|
||||
ret.setCouponRates();
|
||||
|
||||
return ret;
|
||||
} catch (SQLException | RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -673,6 +673,29 @@ public class Commands {
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "debugservercoupons":
|
||||
case "debugcoupons":
|
||||
if(ServerConstants.USE_DEBUG) {
|
||||
String s = "Currently active SERVER coupons: ";
|
||||
for(Integer i : Server.getInstance().getActiveCoupons()) {
|
||||
s += (i + " ");
|
||||
}
|
||||
|
||||
player.dropMessage(s);
|
||||
}
|
||||
break;
|
||||
|
||||
case "debugplayercoupons":
|
||||
if(ServerConstants.USE_DEBUG) {
|
||||
String s = "Currently active PLAYER coupons: ";
|
||||
for(Integer i : Server.getInstance().getActiveCoupons()) {
|
||||
s += (i + " ");
|
||||
}
|
||||
|
||||
player.dropMessage(s);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (player.gmLevel() == 0) {
|
||||
@@ -958,6 +981,12 @@ public class Commands {
|
||||
victim = player;
|
||||
}
|
||||
victim.getClient().disconnect(false, false);
|
||||
} else if (sub[0].equals("togglecoupon")) {
|
||||
if (sub.length < 2){
|
||||
player.yellowMessage("Syntax: !togglecoupon <itemid>");
|
||||
return true;
|
||||
}
|
||||
Server.getInstance().toggleCoupon(Integer.parseInt(sub[1]));
|
||||
} else if (sub[0].equals("exprate")) {
|
||||
if (sub.length < 2){
|
||||
player.yellowMessage("Syntax: !exprate <newrate>");
|
||||
|
||||
@@ -168,5 +168,5 @@ public class Item implements Comparable<Item> {
|
||||
|
||||
public MaplePet getPet() {
|
||||
return pet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,12 +39,14 @@ import server.MapleItemInformationProvider;
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleInventory implements Iterable<Item> {
|
||||
private MapleCharacter owner;
|
||||
private Map<Short, Item> inventory = new LinkedHashMap<>();
|
||||
private byte slotLimit;
|
||||
private MapleInventoryType type;
|
||||
private boolean checked = false;
|
||||
|
||||
public MapleInventory(MapleInventoryType type, byte slotLimit) {
|
||||
public MapleInventory(MapleCharacter mc, MapleInventoryType type, byte slotLimit) {
|
||||
this.owner = mc;
|
||||
this.inventory = new LinkedHashMap<>();
|
||||
this.type = type;
|
||||
this.slotLimit = slotLimit;
|
||||
@@ -91,13 +93,13 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public int countById(int itemId) {
|
||||
int possesed = 0;
|
||||
int qty = 0;
|
||||
for (Item item : inventory.values()) {
|
||||
if (item.getItemId() == itemId) {
|
||||
possesed += item.getQuantity();
|
||||
qty += item.getQuantity();
|
||||
}
|
||||
}
|
||||
return possesed;
|
||||
return qty;
|
||||
}
|
||||
|
||||
public List<Item> listById(int itemId) {
|
||||
@@ -122,7 +124,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
if (slotId < 0 || item == null) {
|
||||
return -1;
|
||||
}
|
||||
inventory.put(slotId, item);
|
||||
addSlot(slotId, item);
|
||||
item.setPosition(slotId);
|
||||
return slotId;
|
||||
}
|
||||
@@ -131,7 +133,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
if (item.getPosition() < 0 && !type.equals(MapleInventoryType.EQUIPPED)) {
|
||||
return;
|
||||
}
|
||||
inventory.put(item.getPosition(), item);
|
||||
addSlot(item.getPosition(), item);
|
||||
}
|
||||
|
||||
public void move(short sSlot, short dSlot, short slotMax) {
|
||||
@@ -193,8 +195,24 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
}
|
||||
|
||||
public void addSlot(short slot, Item item) {
|
||||
inventory.put(slot, item);
|
||||
|
||||
if(MapleItemInformationProvider.getInstance().isRateCoupon(item.getItemId())) {
|
||||
System.out.println("reformulating");
|
||||
owner.revertCouponRates();
|
||||
owner.setCouponRates();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSlot(short slot) {
|
||||
inventory.remove(slot);
|
||||
Item item = inventory.remove(slot);
|
||||
|
||||
if(item != null && MapleItemInformationProvider.getInstance().isRateCoupon(item.getItemId())) {
|
||||
System.out.println("reformulating");
|
||||
owner.revertCouponRates();
|
||||
owner.setCouponRates();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
|
||||
@@ -89,9 +89,9 @@ public class GameConstants {
|
||||
return skillId > 1111002 && skillId < 1111007 || skillId == 11111002 || skillId == 11111003;
|
||||
}
|
||||
|
||||
public static boolean hasSPTable(MapleJob job) {
|
||||
public static boolean hasSPTable(MapleJob job) {
|
||||
switch (job) {
|
||||
case EVAN:
|
||||
case EVAN:
|
||||
case EVAN1:
|
||||
case EVAN2:
|
||||
case EVAN3:
|
||||
|
||||
@@ -10,9 +10,12 @@ public class ServerConstants {
|
||||
public static String[] WORLD_NAMES = {"Scania", "Bera", "Broa", "Windia", "Khaini", "Bellocan", "Mardia", "Kradia", "Yellonde", "Demethos", "Galicia", "El Nido", "Zenith", "Arcenia", "Kastia", "Judis", "Plana", "Kalluna", "Stius", "Croa", "Medere"};
|
||||
|
||||
//Login Configuration
|
||||
public static final int CHANNEL_LOAD = 100; //Players per channel.
|
||||
public static final int CHANNEL_LOAD = 100; //Max players per channel.
|
||||
|
||||
public static final long PURGING_INTERVAL = 5 * 60 * 1000;
|
||||
public static final long RANKING_INTERVAL = 60 * 60 * 1000; //60 minutes, 3600000.
|
||||
public static final boolean ENABLE_PIC = false; //Escolha true/false para ativar ou desativar o Pic.
|
||||
public static final long COUPON_INTERVAL = 60 * 60 * 1000; //60 minutes, 3600000.
|
||||
public static final boolean ENABLE_PIC = false; //Pick true/false to enable or disable Pic.
|
||||
|
||||
//Ip Configuration
|
||||
public static String HOST;
|
||||
@@ -54,6 +57,7 @@ public class ServerConstants {
|
||||
//Public static final boolean USE_ULTRA_THREE_SNAILS = true;
|
||||
public static final boolean USE_ADD_SLOTS_BY_LEVEL = true; //Slots are added each 20 levels.
|
||||
public static final boolean USE_ADD_RATES_BY_LEVEL = true; //Rates are added each 20 levels.
|
||||
public static final boolean USE_STACK_COUPON_RATES = true; //Multiple coupons effects builds up together.
|
||||
public static final int USE_EQUIPMNT_LVLUP = 7; //Nope, not working yet. //all equips lvlup at max level as N, set 0 to disable.
|
||||
public static final int FAME_GAIN_BY_QUEST = 4; //Fame gain each N quest completes, set 0 to disable.
|
||||
public static final int SCROLL_CHANCE_RATE = 10; //Number of tries for success on a scroll, set 0 for default.
|
||||
@@ -63,7 +67,7 @@ public class ServerConstants {
|
||||
public static final double PET_AUTOMP_RATIO = 0.99;
|
||||
|
||||
//Dojo Configuration
|
||||
public static final boolean USE_DEADLY_DOJO = false; //Should bosses really use 1HP,1MP attacks in dojo?.
|
||||
public static final boolean USE_DEADLY_DOJO = false; //Should bosses really use 1HP,1MP attacks in dojo?
|
||||
|
||||
//Pet Hungry Configuration
|
||||
public static final boolean PETS_NEVER_HUNGRY = false; //If true, pets will never grow hungry.
|
||||
|
||||
52
src/net/server/CouponWorker.java
Normal file
52
src/net/server/CouponWorker.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package net.server;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import constants.ServerConstants;
|
||||
import tools.DatabaseConnection;
|
||||
|
||||
import net.server.world.World;
|
||||
import client.MapleCharacter;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
* @info Thread responsible for maintaining coupons EXP & DROP effects active
|
||||
*/
|
||||
public class CouponWorker implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Server.getInstance().updateActiveCoupons();
|
||||
Server.getInstance().commitActiveCoupons();
|
||||
} catch(SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -62,10 +63,13 @@ import tools.Pair;
|
||||
import client.MapleCharacter;
|
||||
import client.SkillFactory;
|
||||
import constants.ServerConstants;
|
||||
import java.util.Calendar;
|
||||
import server.quest.MapleQuest;
|
||||
|
||||
public class Server implements Runnable {
|
||||
|
||||
private final Map<Integer, Integer> couponRates = new LinkedHashMap<>();
|
||||
private final List<Integer> activeCoupons = new LinkedList<>();
|
||||
|
||||
private IoAcceptor acceptor;
|
||||
private List<Map<Integer, String>> channels = new LinkedList<>();
|
||||
private List<World> worlds = new ArrayList<>();
|
||||
@@ -123,6 +127,107 @@ public class Server implements Runnable {
|
||||
public String getIP(int world, int channel) {
|
||||
return channels.get(world).get(channel);
|
||||
}
|
||||
|
||||
private long getTimeLeftForNextHour() {
|
||||
Calendar nextHour = Calendar.getInstance();
|
||||
nextHour.add(Calendar.HOUR, 1);
|
||||
nextHour.set(Calendar.MINUTE, 0);
|
||||
nextHour.set(Calendar.SECOND, 0);
|
||||
|
||||
return Math.max(0, nextHour.getTimeInMillis() - System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getCouponRates() {
|
||||
return couponRates;
|
||||
}
|
||||
|
||||
private void loadCouponRates(Connection c) throws SQLException {
|
||||
PreparedStatement ps = c.prepareStatement("SELECT couponid, rate FROM nxcoupons");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
while(rs.next()) {
|
||||
int cid = rs.getInt("couponid");
|
||||
int rate = rs.getInt("rate");
|
||||
|
||||
couponRates.put(cid, rate);
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
}
|
||||
|
||||
public List<Integer> getActiveCoupons() {
|
||||
synchronized(activeCoupons) {
|
||||
return activeCoupons;
|
||||
}
|
||||
}
|
||||
|
||||
public void commitActiveCoupons() {
|
||||
for(World world: getWorlds()) {
|
||||
for(MapleCharacter chr: world.getPlayerStorage().getAllCharacters()) {
|
||||
if(!chr.isLoggedin()) continue;
|
||||
|
||||
chr.revertCouponRates();
|
||||
chr.setCouponRates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleCoupon(Integer couponId) {
|
||||
if(MapleItemInformationProvider.getInstance().isRateCoupon(couponId)) {
|
||||
synchronized(activeCoupons) {
|
||||
if(activeCoupons.contains(couponId)) {
|
||||
activeCoupons.remove(couponId);
|
||||
}
|
||||
else {
|
||||
activeCoupons.add(couponId);
|
||||
}
|
||||
|
||||
commitActiveCoupons();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateActiveCoupons() throws SQLException {
|
||||
synchronized(activeCoupons) {
|
||||
activeCoupons.clear();
|
||||
Calendar c = Calendar.getInstance();
|
||||
|
||||
int weekDay = c.get(Calendar.DAY_OF_WEEK);
|
||||
int hourDay = c.get(Calendar.HOUR_OF_DAY);
|
||||
|
||||
Connection con = null;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
|
||||
int weekdayMask = (1 << weekDay);
|
||||
PreparedStatement ps = con.prepareStatement("SELECT couponid FROM nxcoupons WHERE (activeday & ?) = ? AND starthour <= ? AND endhour > ?");
|
||||
ps.setInt(1, weekdayMask);
|
||||
ps.setInt(2, weekdayMask);
|
||||
ps.setInt(3, hourDay);
|
||||
ps.setInt(4, hourDay);
|
||||
|
||||
ResultSet rs = ps.executeQuery();
|
||||
while(rs.next()) {
|
||||
activeCoupons.add(rs.getInt("couponid"));
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
|
||||
con.close();
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
|
||||
try {
|
||||
if(con != null && !con.isClosed())
|
||||
con.close();
|
||||
} catch (SQLException ex2) {
|
||||
ex2.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -150,6 +255,9 @@ public class Server implements Runnable {
|
||||
ps = c.prepareStatement("UPDATE characters SET HasMerchant = 0");
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
|
||||
loadCouponRates(c);
|
||||
updateActiveCoupons();
|
||||
} catch (SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
@@ -157,10 +265,14 @@ public class Server implements Runnable {
|
||||
IoBuffer.setAllocator(new SimpleBufferAllocator());
|
||||
acceptor = new NioSocketAcceptor();
|
||||
acceptor.getFilterChain().addLast("codec", (IoFilter) new ProtocolCodecFilter(new MapleCodecFactory()));
|
||||
|
||||
TimerManager tMan = TimerManager.getInstance();
|
||||
tMan.start();
|
||||
tMan.register(tMan.purge(), 300000);//Purging ftw...
|
||||
tMan.register(new RankingWorker(), ServerConstants.RANKING_INTERVAL);
|
||||
tMan.register(tMan.purge(), ServerConstants.PURGING_INTERVAL);//Purging ftw...
|
||||
|
||||
long timeLeft = getTimeLeftForNextHour();
|
||||
tMan.register(new CouponWorker(), ServerConstants.COUPON_INTERVAL, timeLeft);
|
||||
tMan.register(new RankingWorker(), ServerConstants.RANKING_INTERVAL, timeLeft);
|
||||
|
||||
long timeToTake = System.currentTimeMillis();
|
||||
SkillFactory.loadAllSkills();
|
||||
@@ -176,7 +288,6 @@ public class Server implements Runnable {
|
||||
MapleQuest.loadAllQuest();
|
||||
System.out.println("Quest loaded in " + ((System.currentTimeMillis() - timeToTake) / 1000.0) + " seconds\r\n");
|
||||
|
||||
|
||||
try {
|
||||
Integer worldCount = Math.min(ServerConstants.WORLD_NAMES.length, Integer.parseInt(p.getProperty("worlds")));
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
//chr.setRates();
|
||||
//chr.setWorldRates();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public final class DistributeSPHandler extends AbstractMaplePacketHandler {
|
||||
AutobanFactory.PACKET_EDIT.alert(player, "tried to packet edit in distributing sp.");
|
||||
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to use skill " + skillid + " without it being in their job.\r\n");
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
if (skillid % 10000000 > 999 && skillid % 10000000 < 1003) {
|
||||
int total = 0;
|
||||
|
||||
@@ -100,7 +100,8 @@ public final class DueyHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if (!ServerConstants.USE_DUEY){
|
||||
return;
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
byte operation = slea.readByte();
|
||||
@@ -196,6 +197,7 @@ public final class DueyHandler extends AbstractMaplePacketHandler {
|
||||
dp = dueypack;
|
||||
if(dp == null) {
|
||||
System.out.println("Error: Null Duey package!");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,7 +205,6 @@ public final class DueyHandler extends AbstractMaplePacketHandler {
|
||||
if (!MapleInventoryManipulator.checkSpace(c, dp.getItem().getItemId(), dp.getItem().getQuantity(), dp.getItem().getOwner())) {
|
||||
c.getPlayer().dropMessage(1, "Your inventory is full");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
|
||||
return;
|
||||
} else {
|
||||
MapleInventoryManipulator.addFromDrop(c, dp.getItem(), false);
|
||||
|
||||
@@ -35,33 +35,32 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
||||
*/
|
||||
public class EnterCashShopHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
try {
|
||||
MapleCharacter mc = c.getPlayer();
|
||||
MapleCharacter mc = c.getPlayer();
|
||||
|
||||
if (mc.getCashShop().isOpened()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mc.closePlayerInteractions();
|
||||
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs());
|
||||
mc.cancelBuffEffects();
|
||||
mc.cancelExpirationTask();
|
||||
|
||||
c.announce(MaplePacketCreator.openCashShop(c, false));
|
||||
c.announce(MaplePacketCreator.showCashInventory(c));
|
||||
c.announce(MaplePacketCreator.showGifts(mc.getCashShop().loadGifts()));
|
||||
c.announce(MaplePacketCreator.showWishList(mc, false));
|
||||
c.announce(MaplePacketCreator.showCash(mc));
|
||||
|
||||
|
||||
c.getChannelServer().removePlayer(mc);
|
||||
mc.getMap().removePlayer(mc);
|
||||
mc.getCashShop().open(true);
|
||||
mc.saveToDB();
|
||||
if (mc.getCashShop().isOpened()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mc.closePlayerInteractions();
|
||||
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs());
|
||||
mc.cancelBuffEffects();
|
||||
mc.cancelExpirationTask();
|
||||
|
||||
c.announce(MaplePacketCreator.openCashShop(c, false));
|
||||
c.announce(MaplePacketCreator.showCashInventory(c));
|
||||
c.announce(MaplePacketCreator.showGifts(mc.getCashShop().loadGifts()));
|
||||
c.announce(MaplePacketCreator.showWishList(mc, false));
|
||||
c.announce(MaplePacketCreator.showCash(mc));
|
||||
|
||||
c.getChannelServer().removePlayer(mc);
|
||||
mc.getMap().removePlayer(mc);
|
||||
mc.getCashShop().open(true);
|
||||
mc.saveToDB();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
player.changeSkillLevel(SkillFactory.getSkill(10000000 * player.getJobType() + 12), (byte) (player.getLinkedLevel() / 10), 20, -1);
|
||||
player.checkBerserk();
|
||||
player.expirationTask();
|
||||
//player.setRates();
|
||||
//player.setWorldRates();
|
||||
if (GameConstants.hasSPTable(player.getJob()) && player.getJob().getId() != 2001) {
|
||||
player.createDragon();
|
||||
}
|
||||
|
||||
@@ -113,11 +113,11 @@ public class World {
|
||||
public void setExpRate(int exp) {
|
||||
//System.out.println("Setting server EXP Rate to " + exp * ServerConstants.EXP_RATE + "x.");
|
||||
for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) {
|
||||
chr.revertRates(false);
|
||||
chr.revertWorldRates();
|
||||
}
|
||||
this.exprate = exp;
|
||||
for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) {
|
||||
chr.setRates();
|
||||
chr.setWorldRates();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,11 +127,11 @@ public class World {
|
||||
|
||||
public void setDropRate(int drop) {
|
||||
for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) {
|
||||
chr.revertRates(false);
|
||||
chr.revertWorldRates();
|
||||
}
|
||||
this.droprate = drop;
|
||||
for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) {
|
||||
chr.setRates();
|
||||
chr.setWorldRates();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,11 +141,11 @@ public class World {
|
||||
|
||||
public void setMesoRate(int meso) {
|
||||
for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) {
|
||||
chr.revertRates(false);
|
||||
chr.revertWorldRates();
|
||||
}
|
||||
this.mesorate = meso;
|
||||
for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) {
|
||||
chr.setRates();
|
||||
chr.setWorldRates();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,11 +155,11 @@ public class World {
|
||||
|
||||
public void setBossDropRate(int bossdrop) {
|
||||
for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) {
|
||||
chr.revertRates(false);
|
||||
chr.revertWorldRates();
|
||||
}
|
||||
this.bossdroprate = bossdrop;
|
||||
for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) {
|
||||
chr.setRates();
|
||||
chr.setWorldRates();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1294,6 +1294,11 @@ public class MapleItemInformationProvider {
|
||||
public boolean isCash(int itemId) {
|
||||
return itemId / 1000000 == 5 || getEquipStats(itemId).get("cash") == 1;
|
||||
}
|
||||
|
||||
public boolean isRateCoupon(int itemId) {
|
||||
int itemType = itemId / 1000;
|
||||
return itemType == 5211 || itemType == 5360;
|
||||
}
|
||||
|
||||
public Collection<Item> canWearEquipment(MapleCharacter chr, Collection<Item> items) {
|
||||
MapleInventory inv = chr.getInventory(MapleInventoryType.EQUIPPED);
|
||||
|
||||
@@ -32,7 +32,7 @@ public class LogHelper {
|
||||
log += item.getQuantity() + " " + itemName + " from " + name2 + " to " + name1 + " \r\n";;
|
||||
}
|
||||
log += "\r\n\r\n";
|
||||
FilePrinter.printError("trades.txt", log);
|
||||
FilePrinter.print("trades.txt", log);
|
||||
}
|
||||
|
||||
public static void logExpedition(MapleExpedition expedition) {
|
||||
@@ -49,7 +49,7 @@ public class LogHelper {
|
||||
log += message;
|
||||
}
|
||||
log += "\r\n\r\n";
|
||||
FilePrinter.printError("expeditions.txt", log);
|
||||
FilePrinter.print("expeditions.txt", log);
|
||||
}
|
||||
|
||||
public static String getTimeString(long then){
|
||||
@@ -62,13 +62,13 @@ public class LogHelper {
|
||||
public static void logLeaf(MapleCharacter player, boolean gotPrize, String operation) {
|
||||
String timeStamp = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss").format(new Date());
|
||||
String log = player.getName() + (gotPrize ? " used a maple leaf to buy " + operation : " redeemed " + operation + " VP for a leaf") + " - " + timeStamp + "\r\n";
|
||||
FilePrinter.printError("mapleleaves.txt", log);
|
||||
FilePrinter.print("mapleleaves.txt", log);
|
||||
}
|
||||
|
||||
public static void logGacha(MapleCharacter player, int itemid, String map) {
|
||||
String itemName = MapleItemInformationProvider.getInstance().getName(itemid);
|
||||
String timeStamp = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss").format(new Date());
|
||||
String log = player.getName() + " got a " + itemName + "(" + itemid + ") from the " + map + " gachapon. - " + timeStamp + "\r\n";
|
||||
FilePrinter.printError("gachapon.txt", log);
|
||||
FilePrinter.print("gachapon.txt", log);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user