Initial re-upload
This commit is contained in:
30
src/main/java/client/AbstractCharacterListener.java
Normal file
30
src/main/java/client/AbstractCharacterListener.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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 client;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public interface AbstractCharacterListener {
|
||||
void onHpChanged(int oldHp);
|
||||
void onHpmpPoolUpdate();
|
||||
void onStatUpdate();
|
||||
void onAnnounceStatPoolUpdate();
|
||||
}
|
||||
773
src/main/java/client/AbstractCharacterObject.java
Normal file
773
src/main/java/client/AbstractCharacterObject.java
Normal file
@@ -0,0 +1,773 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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 client;
|
||||
|
||||
import config.YamlConfig;
|
||||
import constants.game.GameConstants;
|
||||
import server.maps.AbstractAnimatedMapObject;
|
||||
import server.maps.MapleMap;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* @author RonanLana
|
||||
*/
|
||||
public abstract class AbstractCharacterObject extends AbstractAnimatedMapObject {
|
||||
protected MapleMap map;
|
||||
protected int str, dex, luk, int_, hp, maxhp, mp, maxmp;
|
||||
protected int hpMpApUsed, remainingAp;
|
||||
protected int[] remainingSp = new int[10];
|
||||
protected transient int clientmaxhp, clientmaxmp, localmaxhp = 50, localmaxmp = 5;
|
||||
protected float transienthp = Float.NEGATIVE_INFINITY, transientmp = Float.NEGATIVE_INFINITY;
|
||||
|
||||
private AbstractCharacterListener listener = null;
|
||||
protected Map<Stat, Integer> statUpdates = new HashMap<>();
|
||||
|
||||
protected final Lock effLock = new ReentrantLock(true);
|
||||
protected final Lock statRlock;
|
||||
protected final Lock statWlock;
|
||||
|
||||
protected AbstractCharacterObject() {
|
||||
ReadWriteLock statLock = new ReentrantReadWriteLock(true);
|
||||
this.statRlock = statLock.readLock();
|
||||
this.statWlock = statLock.writeLock();
|
||||
|
||||
for (int i = 0; i < remainingSp.length; i++) {
|
||||
remainingSp[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected void setListener(AbstractCharacterListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void setMap(MapleMap map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public MapleMap getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public int getStr() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return str;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getDex() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return dex;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return int_;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getLuk() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return luk;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getRemainingAp() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return remainingAp;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected int getRemainingSp(int jobid) {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return remainingSp[GameConstants.getSkillBook(jobid)];
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getRemainingSps() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return Arrays.copyOf(remainingSp, remainingSp.length);
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getHpMpApUsed() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return hpMpApUsed;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return hp > 0;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getHp() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return hp;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getMp() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return mp;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getMaxHp() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return maxhp;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getMaxMp() {
|
||||
statRlock.lock();
|
||||
try {
|
||||
return maxmp;
|
||||
} finally {
|
||||
statRlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getClientMaxHp() {
|
||||
return clientmaxhp;
|
||||
}
|
||||
|
||||
public int getClientMaxMp() {
|
||||
return clientmaxmp;
|
||||
}
|
||||
|
||||
public int getCurrentMaxHp() {
|
||||
return localmaxhp;
|
||||
}
|
||||
|
||||
public int getCurrentMaxMp() {
|
||||
return localmaxmp;
|
||||
}
|
||||
|
||||
private void setHpMpApUsed(int mpApUsed) {
|
||||
this.hpMpApUsed = mpApUsed;
|
||||
}
|
||||
|
||||
private void dispatchHpChanged(final int oldHp) {
|
||||
listener.onHpChanged(oldHp);
|
||||
}
|
||||
|
||||
private void dispatchHpmpPoolUpdated() {
|
||||
listener.onHpmpPoolUpdate();
|
||||
}
|
||||
|
||||
private void dispatchStatUpdated() {
|
||||
listener.onStatUpdate();
|
||||
}
|
||||
|
||||
private void dispatchStatPoolUpdateAnnounced() {
|
||||
listener.onAnnounceStatPoolUpdate();
|
||||
}
|
||||
|
||||
protected void setHp(int newHp) {
|
||||
int oldHp = hp;
|
||||
|
||||
int thp = newHp;
|
||||
if (thp < 0) {
|
||||
thp = 0;
|
||||
} else if (thp > localmaxhp) {
|
||||
thp = localmaxhp;
|
||||
}
|
||||
|
||||
if (this.hp != thp) {
|
||||
this.transienthp = Float.NEGATIVE_INFINITY;
|
||||
}
|
||||
this.hp = thp;
|
||||
|
||||
dispatchHpChanged(oldHp);
|
||||
}
|
||||
|
||||
protected void setMp(int newMp) {
|
||||
int tmp = newMp;
|
||||
if (tmp < 0) {
|
||||
tmp = 0;
|
||||
} else if (tmp > localmaxmp) {
|
||||
tmp = localmaxmp;
|
||||
}
|
||||
|
||||
if (this.mp != tmp) {
|
||||
this.transientmp = Float.NEGATIVE_INFINITY;
|
||||
}
|
||||
this.mp = tmp;
|
||||
}
|
||||
|
||||
private void setRemainingAp(int remainingAp) {
|
||||
this.remainingAp = remainingAp;
|
||||
}
|
||||
|
||||
private void setRemainingSp(int remainingSp, int skillbook) {
|
||||
this.remainingSp[skillbook] = remainingSp;
|
||||
}
|
||||
|
||||
protected void setMaxHp(int hp_) {
|
||||
if (this.maxhp < hp_) {
|
||||
this.transienthp = Float.NEGATIVE_INFINITY;
|
||||
}
|
||||
this.maxhp = hp_;
|
||||
this.clientmaxhp = Math.min(30000, hp_);
|
||||
}
|
||||
|
||||
protected void setMaxMp(int mp_) {
|
||||
if (this.maxmp < mp_) {
|
||||
this.transientmp = Float.NEGATIVE_INFINITY;
|
||||
}
|
||||
this.maxmp = mp_;
|
||||
this.clientmaxmp = Math.min(30000, mp_);
|
||||
}
|
||||
|
||||
private static long clampStat(int v, int min, int max) {
|
||||
return (v < min) ? min : ((v > max) ? max : v);
|
||||
}
|
||||
|
||||
private static long calcStatPoolNode(Integer v, int displacement) {
|
||||
long r;
|
||||
if (v == null) {
|
||||
r = -32768;
|
||||
} else {
|
||||
r = clampStat(v, -32767, 32767);
|
||||
}
|
||||
|
||||
return ((r & 0x0FFFF) << displacement);
|
||||
}
|
||||
|
||||
private static long calcStatPoolLong(Integer v1, Integer v2, Integer v3, Integer v4) {
|
||||
long ret = 0;
|
||||
|
||||
ret |= calcStatPoolNode(v1, 48);
|
||||
ret |= calcStatPoolNode(v2, 32);
|
||||
ret |= calcStatPoolNode(v3, 16);
|
||||
ret |= calcStatPoolNode(v4, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void changeStatPool(Long hpMpPool, Long strDexIntLuk, Long newSp, int newAp, boolean silent) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
statUpdates.clear();
|
||||
boolean poolUpdate = false;
|
||||
boolean statUpdate = false;
|
||||
|
||||
if (hpMpPool != null) {
|
||||
short newHp = (short) (hpMpPool >> 48);
|
||||
short newMp = (short) (hpMpPool >> 32);
|
||||
short newMaxHp = (short) (hpMpPool >> 16);
|
||||
short newMaxMp = hpMpPool.shortValue();
|
||||
|
||||
if (newMaxHp != Short.MIN_VALUE) {
|
||||
if (newMaxHp < 50) {
|
||||
newMaxHp = 50;
|
||||
}
|
||||
|
||||
poolUpdate = true;
|
||||
setMaxHp(newMaxHp);
|
||||
statUpdates.put(Stat.MAXHP, clientmaxhp);
|
||||
statUpdates.put(Stat.HP, hp);
|
||||
}
|
||||
|
||||
if (newHp != Short.MIN_VALUE) {
|
||||
setHp(newHp);
|
||||
statUpdates.put(Stat.HP, hp);
|
||||
}
|
||||
|
||||
if (newMaxMp != Short.MIN_VALUE) {
|
||||
if (newMaxMp < 5) {
|
||||
newMaxMp = 5;
|
||||
}
|
||||
|
||||
poolUpdate = true;
|
||||
setMaxMp(newMaxMp);
|
||||
statUpdates.put(Stat.MAXMP, clientmaxmp);
|
||||
statUpdates.put(Stat.MP, mp);
|
||||
}
|
||||
|
||||
if (newMp != Short.MIN_VALUE) {
|
||||
setMp(newMp);
|
||||
statUpdates.put(Stat.MP, mp);
|
||||
}
|
||||
}
|
||||
|
||||
if (strDexIntLuk != null) {
|
||||
short newStr = (short) (strDexIntLuk >> 48);
|
||||
short newDex = (short) (strDexIntLuk >> 32);
|
||||
short newInt = (short) (strDexIntLuk >> 16);
|
||||
short newLuk = strDexIntLuk.shortValue();
|
||||
|
||||
if (newStr >= 4) {
|
||||
setStr(newStr);
|
||||
statUpdates.put(Stat.STR, str);
|
||||
}
|
||||
|
||||
if (newDex >= 4) {
|
||||
setDex(newDex);
|
||||
statUpdates.put(Stat.DEX, dex);
|
||||
}
|
||||
|
||||
if (newInt >= 4) {
|
||||
setInt(newInt);
|
||||
statUpdates.put(Stat.INT, int_);
|
||||
}
|
||||
|
||||
if (newLuk >= 4) {
|
||||
setLuk(newLuk);
|
||||
statUpdates.put(Stat.LUK, luk);
|
||||
}
|
||||
|
||||
if (newAp >= 0) {
|
||||
setRemainingAp(newAp);
|
||||
statUpdates.put(Stat.AVAILABLEAP, remainingAp);
|
||||
}
|
||||
|
||||
statUpdate = true;
|
||||
}
|
||||
|
||||
if (newSp != null) {
|
||||
short sp = (short) (newSp >> 16);
|
||||
short skillbook = newSp.shortValue();
|
||||
|
||||
setRemainingSp(sp, skillbook);
|
||||
statUpdates.put(Stat.AVAILABLESP, remainingSp[skillbook]);
|
||||
}
|
||||
|
||||
if (!statUpdates.isEmpty()) {
|
||||
if (poolUpdate) {
|
||||
dispatchHpmpPoolUpdated();
|
||||
}
|
||||
|
||||
if (statUpdate) {
|
||||
dispatchStatUpdated();
|
||||
}
|
||||
|
||||
if (!silent) {
|
||||
dispatchStatPoolUpdateAnnounced();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void healHpMp() {
|
||||
updateHpMp(30000);
|
||||
}
|
||||
|
||||
public void updateHpMp(int x) {
|
||||
updateHpMp(x, x);
|
||||
}
|
||||
|
||||
public void updateHpMp(int newhp, int newmp) {
|
||||
changeHpMp(newhp, newmp, false);
|
||||
}
|
||||
|
||||
protected void changeHpMp(int newhp, int newmp, boolean silent) {
|
||||
changeHpMpPool(newhp, newmp, null, null, silent);
|
||||
}
|
||||
|
||||
private void changeHpMpPool(Integer hp, Integer mp, Integer maxhp, Integer maxmp, boolean silent) {
|
||||
long hpMpPool = calcStatPoolLong(hp, mp, maxhp, maxmp);
|
||||
changeStatPool(hpMpPool, null, null, -1, silent);
|
||||
}
|
||||
|
||||
public void updateHp(int hp) {
|
||||
updateHpMaxHp(hp, null);
|
||||
}
|
||||
|
||||
public void updateMaxHp(int maxhp) {
|
||||
updateHpMaxHp(null, maxhp);
|
||||
}
|
||||
|
||||
public void updateHpMaxHp(int hp, int maxhp) {
|
||||
updateHpMaxHp(Integer.valueOf(hp), Integer.valueOf(maxhp));
|
||||
}
|
||||
|
||||
private void updateHpMaxHp(Integer hp, Integer maxhp) {
|
||||
changeHpMpPool(hp, null, maxhp, null, false);
|
||||
}
|
||||
|
||||
public void updateMp(int mp) {
|
||||
updateMpMaxMp(mp, null);
|
||||
}
|
||||
|
||||
public void updateMaxMp(int maxmp) {
|
||||
updateMpMaxMp(null, maxmp);
|
||||
}
|
||||
|
||||
public void updateMpMaxMp(int mp, int maxmp) {
|
||||
updateMpMaxMp(Integer.valueOf(mp), Integer.valueOf(maxmp));
|
||||
}
|
||||
|
||||
private void updateMpMaxMp(Integer mp, Integer maxmp) {
|
||||
changeHpMpPool(null, mp, null, maxmp, false);
|
||||
}
|
||||
|
||||
public void updateMaxHpMaxMp(int maxhp, int maxmp) {
|
||||
changeHpMpPool(null, null, maxhp, maxmp, false);
|
||||
}
|
||||
|
||||
protected void enforceMaxHpMp() {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
if (mp > localmaxmp || hp > localmaxhp) {
|
||||
changeHpMp(hp, mp, false);
|
||||
}
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int safeAddHP(int delta) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
if (hp + delta <= 0) {
|
||||
delta = -hp + 1;
|
||||
}
|
||||
|
||||
addHP(delta);
|
||||
return delta;
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void addHP(int delta) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
updateHp(hp + delta);
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void addMP(int delta) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
updateMp(mp + delta);
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void addMPHP(int hpDelta, int mpDelta) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
updateHpMp(hp + hpDelta, mp + mpDelta);
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected void addMaxMPMaxHP(int hpdelta, int mpdelta, boolean silent) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
changeHpMpPool(null, null, maxhp + hpdelta, maxmp + mpdelta, silent);
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void addMaxHP(int delta) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
updateMaxHp(maxhp + delta);
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void addMaxMP(int delta) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
updateMaxMp(maxmp + delta);
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void setStr(int str) {
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
private void setDex(int dex) {
|
||||
this.dex = dex;
|
||||
}
|
||||
|
||||
private void setInt(int int_) {
|
||||
this.int_ = int_;
|
||||
}
|
||||
|
||||
private void setLuk(int luk) {
|
||||
this.luk = luk;
|
||||
}
|
||||
|
||||
public boolean assignStr(int x) {
|
||||
return assignStrDexIntLuk(x, null, null, null);
|
||||
}
|
||||
|
||||
public boolean assignDex(int x) {
|
||||
return assignStrDexIntLuk(null, x, null, null);
|
||||
}
|
||||
|
||||
public boolean assignInt(int x) {
|
||||
return assignStrDexIntLuk(null, null, x, null);
|
||||
}
|
||||
|
||||
public boolean assignLuk(int x) {
|
||||
return assignStrDexIntLuk(null, null, null, x);
|
||||
}
|
||||
|
||||
public boolean assignHP(int deltaHP, int deltaAp) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
if (remainingAp - deltaAp < 0 || hpMpApUsed + deltaAp < 0 || maxhp >= 30000) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long hpMpPool = calcStatPoolLong(null, null, maxhp + deltaHP, maxmp);
|
||||
long strDexIntLuk = calcStatPoolLong(str, dex, int_, luk);
|
||||
|
||||
changeStatPool(hpMpPool, strDexIntLuk, null, remainingAp - deltaAp, false);
|
||||
setHpMpApUsed(hpMpApUsed + deltaAp);
|
||||
return true;
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean assignMP(int deltaMP, int deltaAp) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
if (remainingAp - deltaAp < 0 || hpMpApUsed + deltaAp < 0 || maxmp >= 30000) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long hpMpPool = calcStatPoolLong(null, null, maxhp, maxmp + deltaMP);
|
||||
long strDexIntLuk = calcStatPoolLong(str, dex, int_, luk);
|
||||
|
||||
changeStatPool(hpMpPool, strDexIntLuk, null, remainingAp - deltaAp, false);
|
||||
setHpMpApUsed(hpMpApUsed + deltaAp);
|
||||
return true;
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private static int apAssigned(Integer x) {
|
||||
return x != null ? x : 0;
|
||||
}
|
||||
|
||||
public boolean assignStrDexIntLuk(int deltaStr, int deltaDex, int deltaInt, int deltaLuk) {
|
||||
return assignStrDexIntLuk(Integer.valueOf(deltaStr), Integer.valueOf(deltaDex), Integer.valueOf(deltaInt), Integer.valueOf(deltaLuk));
|
||||
}
|
||||
|
||||
private boolean assignStrDexIntLuk(Integer deltaStr, Integer deltaDex, Integer deltaInt, Integer deltaLuk) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
int apUsed = apAssigned(deltaStr) + apAssigned(deltaDex) + apAssigned(deltaInt) + apAssigned(deltaLuk);
|
||||
if (apUsed > remainingAp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int newStr = str, newDex = dex, newInt = int_, newLuk = luk;
|
||||
if (deltaStr != null) {
|
||||
newStr += deltaStr; // thanks Rohenn for noticing an NPE case after "null" started being used
|
||||
}
|
||||
if (deltaDex != null) {
|
||||
newDex += deltaDex;
|
||||
}
|
||||
if (deltaInt != null) {
|
||||
newInt += deltaInt;
|
||||
}
|
||||
if (deltaLuk != null) {
|
||||
newLuk += deltaLuk;
|
||||
}
|
||||
|
||||
if (newStr < 4 || newStr > YamlConfig.config.server.MAX_AP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newDex < 4 || newDex > YamlConfig.config.server.MAX_AP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newInt < 4 || newInt > YamlConfig.config.server.MAX_AP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newLuk < 4 || newLuk > YamlConfig.config.server.MAX_AP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int newAp = remainingAp - apUsed;
|
||||
updateStrDexIntLuk(newStr, newDex, newInt, newLuk, newAp);
|
||||
return true;
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateStrDexIntLuk(int x) {
|
||||
updateStrDexIntLuk(x, x, x, x, -1);
|
||||
}
|
||||
|
||||
public void changeRemainingAp(int x, boolean silent) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
changeStrDexIntLuk(str, dex, int_, luk, x, silent);
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void gainAp(int deltaAp, boolean silent) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
changeRemainingAp(Math.max(0, remainingAp + deltaAp), silent);
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateStrDexIntLuk(int str, int dex, int int_, int luk, int remainingAp) {
|
||||
changeStrDexIntLuk(str, dex, int_, luk, remainingAp, false);
|
||||
}
|
||||
|
||||
private void changeStrDexIntLuk(Integer str, Integer dex, Integer int_, Integer luk, int remainingAp, boolean silent) {
|
||||
long strDexIntLuk = calcStatPoolLong(str, dex, int_, luk);
|
||||
changeStatPool(null, strDexIntLuk, null, remainingAp, silent);
|
||||
}
|
||||
|
||||
private void changeStrDexIntLukSp(Integer str, Integer dex, Integer int_, Integer luk, int remainingAp, int remainingSp, int skillbook, boolean silent) {
|
||||
long strDexIntLuk = calcStatPoolLong(str, dex, int_, luk);
|
||||
long sp = calcStatPoolLong(0, 0, remainingSp, skillbook);
|
||||
changeStatPool(null, strDexIntLuk, sp, remainingAp, silent);
|
||||
}
|
||||
|
||||
protected void updateStrDexIntLukSp(int str, int dex, int int_, int luk, int remainingAp, int remainingSp, int skillbook) {
|
||||
changeStrDexIntLukSp(str, dex, int_, luk, remainingAp, remainingSp, skillbook, false);
|
||||
}
|
||||
|
||||
protected void setRemainingSp(int[] sps) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
System.arraycopy(sps, 0, remainingSp, 0, sps.length);
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateRemainingSp(int remainingSp, int skillbook) {
|
||||
changeRemainingSp(remainingSp, skillbook, false);
|
||||
}
|
||||
|
||||
protected void changeRemainingSp(int remainingSp, int skillbook, boolean silent) {
|
||||
long sp = calcStatPoolLong(0, 0, remainingSp, skillbook);
|
||||
changeStatPool(null, null, sp, Short.MIN_VALUE, silent);
|
||||
}
|
||||
|
||||
public void gainSp(int deltaSp, int skillbook, boolean silent) {
|
||||
effLock.lock();
|
||||
statWlock.lock();
|
||||
try {
|
||||
changeRemainingSp(Math.max(0, remainingSp[skillbook] + deltaSp), skillbook, silent);
|
||||
} finally {
|
||||
statWlock.unlock();
|
||||
effLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
177
src/main/java/client/BuddyList.java
Normal file
177
src/main/java/client/BuddyList.java
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
import net.packet.Packet;
|
||||
import net.server.PlayerStorage;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.PacketCreator;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
public class BuddyList {
|
||||
public enum BuddyOperation {
|
||||
ADDED, DELETED
|
||||
}
|
||||
|
||||
public enum BuddyAddResult {
|
||||
BUDDYLIST_FULL, ALREADY_ON_LIST, OK
|
||||
}
|
||||
|
||||
private final Map<Integer, BuddylistEntry> buddies = new LinkedHashMap<>();
|
||||
private int capacity;
|
||||
private final Deque<CharacterNameAndId> pendingRequests = new LinkedList<>();
|
||||
|
||||
public BuddyList(int capacity) {
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
public boolean contains(int characterId) {
|
||||
synchronized (buddies) {
|
||||
return buddies.containsKey(characterId);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsVisible(int characterId) {
|
||||
BuddylistEntry ble;
|
||||
synchronized (buddies) {
|
||||
ble = buddies.get(characterId);
|
||||
}
|
||||
|
||||
if (ble == null) {
|
||||
return false;
|
||||
}
|
||||
return ble.isVisible();
|
||||
|
||||
}
|
||||
|
||||
public int getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
public void setCapacity(int capacity) {
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
public BuddylistEntry get(int characterId) {
|
||||
synchronized (buddies) {
|
||||
return buddies.get(characterId);
|
||||
}
|
||||
}
|
||||
|
||||
public BuddylistEntry get(String characterName) {
|
||||
String lowerCaseName = characterName.toLowerCase();
|
||||
for (BuddylistEntry ble : getBuddies()) {
|
||||
if (ble.getName().toLowerCase().equals(lowerCaseName)) {
|
||||
return ble;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void put(BuddylistEntry entry) {
|
||||
synchronized (buddies) {
|
||||
buddies.put(entry.getCharacterId(), entry);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(int characterId) {
|
||||
synchronized (buddies) {
|
||||
buddies.remove(characterId);
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<BuddylistEntry> getBuddies() {
|
||||
synchronized (buddies) {
|
||||
return Collections.unmodifiableCollection(buddies.values());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
synchronized (buddies) {
|
||||
return buddies.size() >= capacity;
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getBuddyIds() {
|
||||
synchronized (buddies) {
|
||||
int[] buddyIds = new int[buddies.size()];
|
||||
int i = 0;
|
||||
for (BuddylistEntry ble : buddies.values()) {
|
||||
buddyIds[i++] = ble.getCharacterId();
|
||||
}
|
||||
return buddyIds;
|
||||
}
|
||||
}
|
||||
|
||||
public void broadcast(Packet packet, PlayerStorage pstorage) {
|
||||
for (int bid : getBuddyIds()) {
|
||||
Character chr = pstorage.getCharacterById(bid);
|
||||
|
||||
if (chr != null && chr.isLoggedinWorld()) {
|
||||
chr.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadFromDb(int characterId) {
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT b.buddyid, b.pending, b.group, c.name as buddyname FROM buddies as b, characters as c WHERE c.id = b.buddyid AND b.characterid = ?")) {
|
||||
ps.setInt(1, characterId);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
if (rs.getInt("pending") == 1) {
|
||||
pendingRequests.push(new CharacterNameAndId(rs.getInt("buddyid"), rs.getString("buddyname")));
|
||||
} else {
|
||||
put(new BuddylistEntry(rs.getString("buddyname"), rs.getString("group"), rs.getInt("buddyid"), (byte) -1, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try (PreparedStatement ps = con.prepareStatement("DELETE FROM buddies WHERE pending = 1 AND characterid = ?")) {
|
||||
ps.setInt(1, characterId);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public CharacterNameAndId pollPendingRequest() {
|
||||
return pendingRequests.pollLast();
|
||||
}
|
||||
|
||||
public void addBuddyRequest(Client c, int cidFrom, String nameFrom, int channelFrom) {
|
||||
put(new BuddylistEntry(nameFrom, "Default Group", cidFrom, channelFrom, false));
|
||||
if (pendingRequests.isEmpty()) {
|
||||
c.sendPacket(PacketCreator.requestBuddylistAdd(cidFrom, c.getPlayer().getId(), nameFrom));
|
||||
} else {
|
||||
pendingRequests.push(new CharacterNameAndId(cidFrom, nameFrom));
|
||||
}
|
||||
}
|
||||
}
|
||||
106
src/main/java/client/BuddylistEntry.java
Normal file
106
src/main/java/client/BuddylistEntry.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
public class BuddylistEntry {
|
||||
private final String name;
|
||||
private String group;
|
||||
private final int cid;
|
||||
private int channel;
|
||||
private boolean visible;
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param characterId
|
||||
* @param channel should be -1 if the buddy is offline
|
||||
* @param visible
|
||||
*/
|
||||
public BuddylistEntry(String name, String group, int characterId, int channel, boolean visible) {
|
||||
this.name = name;
|
||||
this.group = group;
|
||||
this.cid = characterId;
|
||||
this.channel = channel;
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the channel the character is on. If the character is offline returns -1.
|
||||
*/
|
||||
public int getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public void setChannel(int channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
return channel >= 0;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public int getCharacterId() {
|
||||
return cid;
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
public void changeGroup(String group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + cid;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final BuddylistEntry other = (BuddylistEntry) obj;
|
||||
return cid == other.cid;
|
||||
}
|
||||
}
|
||||
148
src/main/java/client/BuffStat.java
Normal file
148
src/main/java/client/BuffStat.java
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
public enum BuffStat {
|
||||
//SLOW(0x1L),
|
||||
MORPH(0x2L),
|
||||
RECOVERY(0x4L),
|
||||
MAPLE_WARRIOR(0x8L),
|
||||
STANCE(0x10L),
|
||||
SHARP_EYES(0x20L),
|
||||
MANA_REFLECTION(0x40L),
|
||||
//ALWAYS_RIGHT(0X80L),
|
||||
SHADOW_CLAW(0x100L),
|
||||
INFINITY(0x200L),
|
||||
HOLY_SHIELD(0x400L),
|
||||
HAMSTRING(0x800L),
|
||||
BLIND(0x1000L),
|
||||
CONCENTRATE(0x2000L),
|
||||
PUPPET(0x4000L),
|
||||
ECHO_OF_HERO(0x8000L),
|
||||
MESO_UP_BY_ITEM(0x10000L),
|
||||
GHOST_MORPH(0x20000L),
|
||||
AURA(0x40000L),
|
||||
CONFUSE(0x80000L),
|
||||
|
||||
// ------ COUPON feature ------
|
||||
COUPON_EXP1(0x100000L),
|
||||
COUPON_EXP2(0x200000L),
|
||||
COUPON_EXP3(0x400000L), COUPON_EXP4(0x400000L),
|
||||
COUPON_DRP1(0x800000L),
|
||||
COUPON_DRP2(0x1000000L), COUPON_DRP3(0x1000000L),
|
||||
|
||||
// ------ monster card buffs, thanks to Arnah (Vertisy) ------
|
||||
ITEM_UP_BY_ITEM(0x100000L),
|
||||
RESPECT_PIMMUNE(0x200000L),
|
||||
RESPECT_MIMMUNE(0x400000L),
|
||||
DEFENSE_ATT(0x800000L),
|
||||
DEFENSE_STATE(0x1000000L),
|
||||
|
||||
HPREC(0x2000000L),
|
||||
MPREC(0x4000000L),
|
||||
BERSERK_FURY(0x8000000L),
|
||||
DIVINE_BODY(0x10000000L),
|
||||
SPARK(0x20000000L),
|
||||
MAP_CHAIR(0x40000000L),
|
||||
FINALATTACK(0x80000000L),
|
||||
WATK(0x100000000L),
|
||||
WDEF(0x200000000L),
|
||||
MATK(0x400000000L),
|
||||
MDEF(0x800000000L),
|
||||
ACC(0x1000000000L),
|
||||
AVOID(0x2000000000L),
|
||||
HANDS(0x4000000000L),
|
||||
SPEED(0x8000000000L),
|
||||
JUMP(0x10000000000L),
|
||||
MAGIC_GUARD(0x20000000000L),
|
||||
DARKSIGHT(0x40000000000L),
|
||||
BOOSTER(0x80000000000L),
|
||||
POWERGUARD(0x100000000000L),
|
||||
HYPERBODYHP(0x200000000000L),
|
||||
HYPERBODYMP(0x400000000000L),
|
||||
INVINCIBLE(0x800000000000L),
|
||||
SOULARROW(0x1000000000000L),
|
||||
STUN(0x2000000000000L),
|
||||
POISON(0x4000000000000L),
|
||||
SEAL(0x8000000000000L),
|
||||
DARKNESS(0x10000000000000L),
|
||||
COMBO(0x20000000000000L),
|
||||
SUMMON(0x20000000000000L),
|
||||
WK_CHARGE(0x40000000000000L),
|
||||
DRAGONBLOOD(0x80000000000000L),
|
||||
HOLY_SYMBOL(0x100000000000000L),
|
||||
MESOUP(0x200000000000000L),
|
||||
SHADOWPARTNER(0x400000000000000L),
|
||||
PICKPOCKET(0x800000000000000L),
|
||||
MESOGUARD(0x1000000000000000L),
|
||||
EXP_INCREASE(0x2000000000000000L),
|
||||
WEAKEN(0x4000000000000000L),
|
||||
MAP_PROTECTION(0x8000000000000000L),
|
||||
|
||||
//all incorrect buffstats
|
||||
SLOW(0x200000000L, true),
|
||||
ELEMENTAL_RESET(0x200000000L, true),
|
||||
MAGIC_SHIELD(0x400000000L, true),
|
||||
MAGIC_RESISTANCE(0x800000000L, true),
|
||||
// needs Soul Stone
|
||||
//end incorrect buffstats
|
||||
|
||||
WIND_WALK(0x400000000L, true),
|
||||
ARAN_COMBO(0x1000000000L, true),
|
||||
COMBO_DRAIN(0x2000000000L, true),
|
||||
COMBO_BARRIER(0x4000000000L, true),
|
||||
BODY_PRESSURE(0x8000000000L, true),
|
||||
SMART_KNOCKBACK(0x10000000000L, true),
|
||||
BERSERK(0x20000000000L, true),
|
||||
ENERGY_CHARGE(0x4000000000000L, true),
|
||||
DASH2(0x8000000000000L, true), // correct (speed)
|
||||
DASH(0x10000000000000L, true), // correct (jump)
|
||||
MONSTER_RIDING(0x20000000000000L, true),
|
||||
SPEED_INFUSION(0x40000000000000L, true),
|
||||
HOMING_BEACON(0x80000000000000L, true);
|
||||
|
||||
private final long i;
|
||||
private final boolean isFirst;
|
||||
|
||||
BuffStat(long i, boolean isFirst) {
|
||||
this.i = i;
|
||||
this.isFirst = isFirst;
|
||||
}
|
||||
|
||||
BuffStat(long i) {
|
||||
this.i = i;
|
||||
this.isFirst = false;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return i;
|
||||
}
|
||||
|
||||
public boolean isFirst() {
|
||||
return isFirst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
11242
src/main/java/client/Character.java
Normal file
11242
src/main/java/client/Character.java
Normal file
File diff suppressed because it is too large
Load Diff
41
src/main/java/client/CharacterNameAndId.java
Normal file
41
src/main/java/client/CharacterNameAndId.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
public class CharacterNameAndId {
|
||||
private final int id;
|
||||
private final String name;
|
||||
|
||||
public CharacterNameAndId(int id, String name) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
1584
src/main/java/client/Client.java
Normal file
1584
src/main/java/client/Client.java
Normal file
File diff suppressed because it is too large
Load Diff
19
src/main/java/client/DefaultDates.java
Normal file
19
src/main/java/client/DefaultDates.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package client;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
final public class DefaultDates {
|
||||
// May 11 2005 is the date MapleGlobal released, so it's a symbolic default value
|
||||
|
||||
private DefaultDates() {
|
||||
}
|
||||
|
||||
public static LocalDate getBirthday() {
|
||||
return LocalDate.parse("2005-05-11");
|
||||
}
|
||||
|
||||
public static LocalDateTime getTempban() {
|
||||
return LocalDateTime.parse("2005-05-11T00:00:00");
|
||||
}
|
||||
}
|
||||
90
src/main/java/client/Disease.java
Normal file
90
src/main/java/client/Disease.java
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
import constants.game.GameConstants;
|
||||
import server.life.MobSkillType;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum Disease {
|
||||
NULL(0x0),
|
||||
SLOW(0x1, MobSkillType.SLOW),
|
||||
SEDUCE(0x80, MobSkillType.SEDUCE),
|
||||
FISHABLE(0x100),
|
||||
ZOMBIFY(0x4000),
|
||||
CONFUSE(0x80000, MobSkillType.REVERSE_INPUT),
|
||||
STUN(0x2000000000000L, MobSkillType.STUN),
|
||||
POISON(0x4000000000000L, MobSkillType.POISON),
|
||||
SEAL(0x8000000000000L, MobSkillType.SEAL),
|
||||
DARKNESS(0x10000000000000L, MobSkillType.DARKNESS),
|
||||
WEAKEN(0x4000000000000000L, MobSkillType.WEAKNESS),
|
||||
CURSE(0x8000000000000000L, MobSkillType.CURSE);
|
||||
|
||||
private final long i;
|
||||
private final MobSkillType mobSkillType;
|
||||
|
||||
Disease(long i) {
|
||||
this(i, null);
|
||||
}
|
||||
|
||||
Disease(long i, MobSkillType skill) {
|
||||
this.i = i;
|
||||
this.mobSkillType = skill;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return i;
|
||||
}
|
||||
|
||||
public boolean isFirst() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public MobSkillType getMobSkillType() {
|
||||
return mobSkillType;
|
||||
}
|
||||
|
||||
public static Disease ordinal(int ord) {
|
||||
try {
|
||||
return Disease.values()[ord];
|
||||
} catch (IndexOutOfBoundsException io) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public static final Disease getRandom() {
|
||||
Disease[] diseases = GameConstants.CPQ_DISEASES;
|
||||
return diseases[(int) (Math.random() * diseases.length)];
|
||||
}
|
||||
|
||||
public static final Disease getBySkill(MobSkillType skill) {
|
||||
if (skill == null) {
|
||||
return null;
|
||||
}
|
||||
return Arrays.stream(Disease.values())
|
||||
.filter(d -> d.mobSkillType == skill)
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
33
src/main/java/client/DiseaseValueHolder.java
Normal file
33
src/main/java/client/DiseaseValueHolder.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 ~ 2010 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 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 client;
|
||||
|
||||
/**
|
||||
* @author anybody can do this
|
||||
*/
|
||||
public class DiseaseValueHolder {
|
||||
public long startTime, length;
|
||||
|
||||
public DiseaseValueHolder(long start, long length) {
|
||||
this.startTime = start;
|
||||
this.length = length;
|
||||
}
|
||||
}
|
||||
308
src/main/java/client/Family.java
Normal file
308
src/main/java/client/Family.java
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
import net.packet.Packet;
|
||||
import net.server.Server;
|
||||
import net.server.world.World;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.PacketCreator;
|
||||
import tools.Pair;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @author Jay Estrella - Mr.Trash :3
|
||||
* @author Ubaware
|
||||
*/
|
||||
public class Family {
|
||||
private static final Logger log = LoggerFactory.getLogger(Family.class);
|
||||
private static final AtomicInteger familyIDCounter = new AtomicInteger();
|
||||
|
||||
private final int id, world;
|
||||
private final Map<Integer, FamilyEntry> members = new ConcurrentHashMap<>();
|
||||
private FamilyEntry leader;
|
||||
private String name;
|
||||
private String preceptsMessage = "";
|
||||
private int totalGenerations;
|
||||
|
||||
public Family(int id, int world) {
|
||||
int newId = id;
|
||||
if (id == -1) {
|
||||
// get next available family id
|
||||
while (idInUse(newId = familyIDCounter.incrementAndGet())) {
|
||||
}
|
||||
}
|
||||
this.id = newId;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
private static boolean idInUse(int id) {
|
||||
for (World world : Server.getInstance().getWorlds()) {
|
||||
if (world.getFamily(id) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public void setLeader(FamilyEntry leader) {
|
||||
this.leader = leader;
|
||||
setName(leader.getName());
|
||||
}
|
||||
|
||||
public FamilyEntry getLeader() {
|
||||
return leader;
|
||||
}
|
||||
|
||||
private void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getTotalMembers() {
|
||||
return members.size();
|
||||
}
|
||||
|
||||
public int getTotalGenerations() {
|
||||
return totalGenerations;
|
||||
}
|
||||
|
||||
public void setTotalGenerations(int generations) {
|
||||
this.totalGenerations = generations;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setMessage(String message, boolean save) {
|
||||
this.preceptsMessage = message;
|
||||
if (save) {
|
||||
try (Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("UPDATE family_character SET precepts = ? WHERE cid = ?")) {
|
||||
ps.setString(1, message);
|
||||
ps.setInt(2, getLeader().getChrId());
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not save new precepts for family {}", getID(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return preceptsMessage;
|
||||
}
|
||||
|
||||
public void addEntry(FamilyEntry entry) {
|
||||
members.put(entry.getChrId(), entry);
|
||||
}
|
||||
|
||||
public void removeEntryBranch(FamilyEntry root) {
|
||||
members.remove(root.getChrId());
|
||||
for (FamilyEntry junior : root.getJuniors()) {
|
||||
if (junior != null) {
|
||||
removeEntryBranch(junior);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addEntryTree(FamilyEntry root) {
|
||||
members.put(root.getChrId(), root);
|
||||
for (FamilyEntry junior : root.getJuniors()) {
|
||||
if (junior != null) {
|
||||
addEntryTree(junior);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FamilyEntry getEntryByID(int cid) {
|
||||
return members.get(cid);
|
||||
}
|
||||
|
||||
public void broadcast(Packet packet) {
|
||||
broadcast(packet, -1);
|
||||
}
|
||||
|
||||
public void broadcast(Packet packet, int ignoreID) {
|
||||
for (FamilyEntry entry : members.values()) {
|
||||
Character chr = entry.getChr();
|
||||
if (chr != null) {
|
||||
if (chr.getId() == ignoreID) {
|
||||
continue;
|
||||
}
|
||||
chr.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void broadcastFamilyInfoUpdate() {
|
||||
for (FamilyEntry entry : members.values()) {
|
||||
Character chr = entry.getChr();
|
||||
if (chr != null) {
|
||||
chr.sendPacket(PacketCreator.getFamilyInfo(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void resetDailyReps() {
|
||||
for (FamilyEntry entry : members.values()) {
|
||||
entry.setTodaysRep(0);
|
||||
entry.setRepsToSenior(0);
|
||||
entry.resetEntitlementUsages();
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadAllFamilies(Connection con) {
|
||||
List<Pair<Pair<Integer, Integer>, FamilyEntry>> unmatchedJuniors = new ArrayList<>(200); // <<world, seniorid> familyEntry>
|
||||
try (PreparedStatement psEntries = con.prepareStatement("SELECT * FROM family_character")) {
|
||||
ResultSet rsEntries = psEntries.executeQuery();
|
||||
while (rsEntries.next()) { // can be optimized
|
||||
int cid = rsEntries.getInt("cid");
|
||||
String name = null;
|
||||
int level = -1;
|
||||
int jobID = -1;
|
||||
int world = -1;
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT world, name, level, job FROM characters WHERE id = ?")) {
|
||||
ps.setInt(1, cid);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if (rs.next()) {
|
||||
world = rs.getInt("world");
|
||||
name = rs.getString("name");
|
||||
level = rs.getInt("level");
|
||||
jobID = rs.getInt("job");
|
||||
} else {
|
||||
log.error("Could not load character information of chrId {} in loadAllFamilies(). (RECORD DOES NOT EXIST)", cid);
|
||||
continue;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not load character information of chrId {} in loadAllFamilies(). (SQL ERROR)", cid, e);
|
||||
continue;
|
||||
}
|
||||
int familyid = rsEntries.getInt("familyid");
|
||||
int seniorid = rsEntries.getInt("seniorid");
|
||||
int reputation = rsEntries.getInt("reputation");
|
||||
int todaysRep = rsEntries.getInt("todaysrep");
|
||||
int totalRep = rsEntries.getInt("totalreputation");
|
||||
int repsToSenior = rsEntries.getInt("reptosenior");
|
||||
String precepts = rsEntries.getString("precepts");
|
||||
//Timestamp lastResetTime = rsEntries.getTimestamp("lastresettime"); //taken care of by FamilyDailyResetTask
|
||||
World wserv = Server.getInstance().getWorld(world);
|
||||
if (wserv == null) {
|
||||
continue;
|
||||
}
|
||||
Family family = wserv.getFamily(familyid);
|
||||
if (family == null) {
|
||||
family = new Family(familyid, world);
|
||||
Server.getInstance().getWorld(world).addFamily(familyid, family);
|
||||
}
|
||||
FamilyEntry familyEntry = new FamilyEntry(family, cid, name, level, Job.getById(jobID));
|
||||
family.addEntry(familyEntry);
|
||||
if (seniorid <= 0) {
|
||||
family.setLeader(familyEntry);
|
||||
family.setMessage(precepts, false);
|
||||
}
|
||||
FamilyEntry senior = family.getEntryByID(seniorid);
|
||||
if (senior != null) {
|
||||
familyEntry.setSenior(family.getEntryByID(seniorid), false);
|
||||
} else {
|
||||
if (seniorid > 0) {
|
||||
unmatchedJuniors.add(new Pair<>(new Pair<>(world, seniorid), familyEntry));
|
||||
}
|
||||
}
|
||||
familyEntry.setReputation(reputation);
|
||||
familyEntry.setTodaysRep(todaysRep);
|
||||
familyEntry.setTotalReputation(totalRep);
|
||||
familyEntry.setRepsToSenior(repsToSenior);
|
||||
//load used entitlements
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT entitlementid FROM family_entitlement WHERE charid = ?")) {
|
||||
ps.setInt(1, familyEntry.getChrId());
|
||||
ResultSet rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
familyEntry.setEntitlementUsed(rs.getInt("entitlementid"));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not get family_character entries", e);
|
||||
}
|
||||
// link missing ones (out of order)
|
||||
for (Pair<Pair<Integer, Integer>, FamilyEntry> unmatchedJunior : unmatchedJuniors) {
|
||||
int world = unmatchedJunior.getLeft().getLeft();
|
||||
int seniorid = unmatchedJunior.getLeft().getRight();
|
||||
FamilyEntry junior = unmatchedJunior.getRight();
|
||||
FamilyEntry senior = Server.getInstance().getWorld(world).getFamily(junior.getFamily().getID()).getEntryByID(seniorid);
|
||||
if (senior != null) {
|
||||
junior.setSenior(senior, false);
|
||||
} else {
|
||||
log.error("Missing senior for chr {} in world {}", junior.getName(), world);
|
||||
}
|
||||
}
|
||||
|
||||
for (World world : Server.getInstance().getWorlds()) {
|
||||
for (Family family : world.getFamilies()) {
|
||||
family.getLeader().doFullCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void saveAllMembersRep() { //was used for autosave task, but character autosave should be enough
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
con.setAutoCommit(false);
|
||||
boolean success = true;
|
||||
for (FamilyEntry entry : members.values()) {
|
||||
success = entry.saveReputation(con);
|
||||
if (!success) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
con.rollback();
|
||||
log.error("Family rep autosave failed for family {}", getID());
|
||||
}
|
||||
con.setAutoCommit(true);
|
||||
//reset repChanged after successful save
|
||||
for (FamilyEntry entry : members.values()) {
|
||||
entry.savedSuccessfully();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not get connection to DB while saving all members rep", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
src/main/java/client/FamilyEntitlement.java
Normal file
41
src/main/java/client/FamilyEntitlement.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package client;
|
||||
|
||||
public enum FamilyEntitlement {
|
||||
FAMILY_REUINION(1, 300, "Family Reunion", "[Target] Me\\n[Effect] Teleport directly to the Family member of your choice."),
|
||||
SUMMON_FAMILY(1, 500, "Summon Family", "[Target] 1 Family member\\n[Effect] Summon a Family member of choice to the map you're in."),
|
||||
SELF_DROP_1_5(1, 700, "My Drop Rate 1.5x (15 min)", "[Target] Me\\n[Time] 15 min.\\n[Effect] Monster drop rate will be increased #c1.5x#.\\n* If the Drop Rate event is in progress, this will be nullified."),
|
||||
SELF_EXP_1_5(1, 800, "My EXP 1.5x (15 min)", "[Target] Me\\n[Time] 15 min.\\n[Effect] EXP earned from hunting will be increased #c1.5x#.\\n* If the EXP event is in progress, this will be nullified."),
|
||||
FAMILY_BONDING(1, 1000, "Family Bonding (30 min)", "[Target] At least 6 Family members online that are below me in the Pedigree\\n[Time] 30 min.\\n[Effect] Monster drop rate and EXP earned will be increased #c2x#. \\n* If the EXP event is in progress, this will be nullified."),
|
||||
SELF_DROP_2(1, 1200, "My Drop Rate 2x (15 min)", "[Target] Me\\n[Time] 15 min.\\n[Effect] Monster drop rate will be increased #c2x#.\\n* If the Drop Rate event is in progress, this will be nullified."),
|
||||
SELF_EXP_2(1, 1500, "My EXP 2x (15 min)", "[Target] Me\\n[Time] 15 min.\\n[Effect] EXP earned from hunting will be increased #c2x#.\\n* If the EXP event is in progress, this will be nullified."),
|
||||
SELF_DROP_2_30MIN(1, 2000, "My Drop Rate 2x (30 min)", "[Target] Me\\n[Time] 30 min.\\n[Effect] Monster drop rate will be increased #c2x#.\\n* If the Drop Rate event is in progress, this will be nullified."),
|
||||
SELF_EXP_2_30MIN(1, 2500, "My EXP 2x (30 min)", "[Target] Me\\n[Time] 30 min.\\n[Effect] EXP earned from hunting will be increased #c2x#. \\n* If the EXP event is in progress, this will be nullified."),
|
||||
PARTY_DROP_2_30MIN(1, 4000, "My Party Drop Rate 2x (30 min)", "[Target] My party\\n[Time] 30 min.\\n[Effect] Monster drop rate will be increased #c2x#.\\n* If the Drop Rate event is in progress, this will be nullified."),
|
||||
PARTY_EXP_2_30MIN(1, 5000, "My Party EXP 2x (30 min)", "[Target] My party\\n[Time] 30 min.\\n[Effect] EXP earned from hunting will be increased #c2x#.\\n* If the EXP event is in progress, this will be nullified.");
|
||||
|
||||
private final int usageLimit, repCost;
|
||||
private final String name, description;
|
||||
|
||||
FamilyEntitlement(int usageLimit, int repCost, String name, String description) {
|
||||
this.usageLimit = usageLimit;
|
||||
this.repCost = repCost;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getUsageLimit() {
|
||||
return usageLimit;
|
||||
}
|
||||
|
||||
public int getRepCost() {
|
||||
return repCost;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
619
src/main/java/client/FamilyEntry.java
Normal file
619
src/main/java/client/FamilyEntry.java
Normal file
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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 client;
|
||||
|
||||
import net.packet.Packet;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.PacketCreator;
|
||||
import tools.Pair;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Ubaware
|
||||
*/
|
||||
|
||||
public class FamilyEntry {
|
||||
private static final Logger log = LoggerFactory.getLogger(FamilyEntry.class);
|
||||
|
||||
private final int characterID;
|
||||
private volatile Family family;
|
||||
private volatile Character character;
|
||||
|
||||
private volatile FamilyEntry senior;
|
||||
private final FamilyEntry[] juniors = new FamilyEntry[2];
|
||||
private final int[] entitlements = new int[11];
|
||||
private volatile int reputation, totalReputation;
|
||||
private volatile int todaysRep, repsToSenior; //both are daily values
|
||||
private volatile int totalJuniors, totalSeniors;
|
||||
|
||||
private volatile int generation;
|
||||
|
||||
private volatile boolean repChanged; //used to ignore saving unchanged rep values
|
||||
|
||||
// cached values for offline players
|
||||
private String charName;
|
||||
private int level;
|
||||
private Job job;
|
||||
|
||||
public FamilyEntry(Family family, int characterID, String charName, int level, Job job) {
|
||||
this.family = family;
|
||||
this.characterID = characterID;
|
||||
this.charName = charName;
|
||||
this.level = level;
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
public Character getChr() {
|
||||
return character;
|
||||
}
|
||||
|
||||
public void setCharacter(Character newCharacter) {
|
||||
if (newCharacter == null) {
|
||||
cacheOffline(newCharacter);
|
||||
} else {
|
||||
newCharacter.setFamilyEntry(this);
|
||||
}
|
||||
this.character = newCharacter;
|
||||
}
|
||||
|
||||
private void cacheOffline(Character chr) {
|
||||
if (chr != null) {
|
||||
charName = chr.getName();
|
||||
level = chr.getLevel();
|
||||
job = chr.getJob();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void join(FamilyEntry senior) {
|
||||
if (senior == null || getSenior() != null) {
|
||||
return;
|
||||
}
|
||||
Family oldFamily = getFamily();
|
||||
Family newFamily = senior.getFamily();
|
||||
setSenior(senior, false);
|
||||
addSeniorCount(newFamily.getTotalGenerations(), newFamily); //count will be overwritten by doFullCount()
|
||||
newFamily.getLeader().doFullCount(); //easier than keeping track of numbers
|
||||
oldFamily.setMessage(null, true);
|
||||
newFamily.addEntryTree(this);
|
||||
Server.getInstance().getWorld(oldFamily.getWorld()).removeFamily(oldFamily.getID());
|
||||
|
||||
//db
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
con.setAutoCommit(false);
|
||||
boolean success = updateDBChangeFamily(con, getChrId(), newFamily.getID(), senior.getChrId());
|
||||
for (FamilyEntry junior : juniors) { // better to duplicate this than the SQL code
|
||||
if (junior != null) {
|
||||
success = junior.updateNewFamilyDB(con); // recursively updates juniors in db
|
||||
if (!success) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
con.rollback();
|
||||
log.error("Could not absorb {}'s family into {}'s family. (SQL ERROR)", oldFamily.getName(), newFamily.getName());
|
||||
}
|
||||
con.setAutoCommit(true);
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not get connection to DB when joining families", e);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void fork() {
|
||||
Family oldFamily = getFamily();
|
||||
FamilyEntry oldSenior = getSenior();
|
||||
family = new Family(-1, oldFamily.getWorld());
|
||||
Server.getInstance().getWorld(family.getWorld()).addFamily(family.getID(), family);
|
||||
setSenior(null, false);
|
||||
family.setLeader(this);
|
||||
addSeniorCount(-getTotalSeniors(), family);
|
||||
setTotalSeniors(0);
|
||||
if (oldSenior != null) {
|
||||
oldSenior.addJuniorCount(-getTotalJuniors());
|
||||
oldSenior.removeJunior(this);
|
||||
oldFamily.getLeader().doFullCount();
|
||||
}
|
||||
oldFamily.removeEntryBranch(this);
|
||||
family.addEntryTree(this);
|
||||
this.repsToSenior = 0;
|
||||
this.repChanged = true;
|
||||
family.setMessage("", true);
|
||||
doFullCount(); //to make sure all counts are correct
|
||||
// update db
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
con.setAutoCommit(false);
|
||||
|
||||
boolean success = updateDBChangeFamily(con, getChrId(), getFamily().getID(), 0);
|
||||
|
||||
for (FamilyEntry junior : juniors) { // better to duplicate this than the SQL code
|
||||
if (junior != null) {
|
||||
success = junior.updateNewFamilyDB(con); // recursively updates juniors in db
|
||||
if (!success) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
con.rollback();
|
||||
log.error("Could not fork family with new leader {}. (Old senior: {}, leader: {})", getName(), oldSenior.getName(), oldFamily.getLeader().getName());
|
||||
}
|
||||
con.setAutoCommit(true);
|
||||
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not get connection to DB when forking families", e);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized boolean updateNewFamilyDB(Connection con) {
|
||||
if (!updateFamilyEntryDB(con, getChrId(), getFamily().getID())) {
|
||||
return false;
|
||||
}
|
||||
if (!updateCharacterFamilyDB(con, getChrId(), getFamily().getID(), true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (FamilyEntry junior : juniors) {
|
||||
if (junior != null) {
|
||||
if (!junior.updateNewFamilyDB(con)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean updateFamilyEntryDB(Connection con, int cid, int familyid) {
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE family_character SET familyid = ? WHERE cid = ?")) {
|
||||
ps.setInt(1, familyid);
|
||||
ps.setInt(2, cid);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not update family id in 'family_character' for chrId {}. (fork)", cid, e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private synchronized void addSeniorCount(int seniorCount, Family newFamily) { // traverses tree and subtracts seniors and updates family
|
||||
if (newFamily != null) {
|
||||
this.family = newFamily;
|
||||
}
|
||||
setTotalSeniors(getTotalSeniors() + seniorCount);
|
||||
this.generation += seniorCount;
|
||||
for (FamilyEntry junior : juniors) {
|
||||
if (junior != null) {
|
||||
junior.addSeniorCount(seniorCount, newFamily);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void addJuniorCount(int juniorCount) { // climbs tree and adds junior count
|
||||
setTotalJuniors(getTotalJuniors() + juniorCount);
|
||||
FamilyEntry senior = getSenior();
|
||||
if (senior != null) {
|
||||
senior.addJuniorCount(juniorCount);
|
||||
}
|
||||
}
|
||||
|
||||
public Family getFamily() {
|
||||
return family;
|
||||
}
|
||||
|
||||
public int getChrId() {
|
||||
return characterID;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
Character chr = character;
|
||||
if (chr != null) {
|
||||
return chr.getName();
|
||||
} else {
|
||||
return charName;
|
||||
}
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
Character chr = character;
|
||||
if (chr != null) {
|
||||
return chr.getLevel();
|
||||
} else {
|
||||
return level;
|
||||
}
|
||||
}
|
||||
|
||||
public Job getJob() {
|
||||
Character chr = character;
|
||||
if (chr != null) {
|
||||
return chr.getJob();
|
||||
} else {
|
||||
return job;
|
||||
}
|
||||
}
|
||||
|
||||
public int getReputation() {
|
||||
return reputation;
|
||||
}
|
||||
|
||||
public int getTodaysRep() {
|
||||
return todaysRep;
|
||||
}
|
||||
|
||||
public void setReputation(int reputation) {
|
||||
if (reputation != this.reputation) {
|
||||
this.repChanged = true;
|
||||
}
|
||||
this.reputation = reputation;
|
||||
}
|
||||
|
||||
public void setTodaysRep(int today) {
|
||||
if (today != todaysRep) {
|
||||
this.repChanged = true;
|
||||
}
|
||||
this.todaysRep = today;
|
||||
}
|
||||
|
||||
public int getRepsToSenior() {
|
||||
return repsToSenior;
|
||||
}
|
||||
|
||||
public void setRepsToSenior(int reputation) {
|
||||
if (reputation != this.repsToSenior) {
|
||||
this.repChanged = true;
|
||||
}
|
||||
this.repsToSenior = reputation;
|
||||
}
|
||||
|
||||
public void gainReputation(int gain, boolean countTowardsTotal) {
|
||||
gainReputation(gain, countTowardsTotal, this);
|
||||
}
|
||||
|
||||
private void gainReputation(int gain, boolean countTowardsTotal, FamilyEntry from) {
|
||||
if (gain != 0) {
|
||||
repChanged = true;
|
||||
}
|
||||
this.reputation += gain;
|
||||
this.todaysRep += gain;
|
||||
if (gain > 0 && countTowardsTotal) {
|
||||
this.totalReputation += gain;
|
||||
}
|
||||
Character chr = getChr();
|
||||
if (chr != null) {
|
||||
chr.sendPacket(PacketCreator.sendGainRep(gain, from != null ? from.getName() : ""));
|
||||
}
|
||||
}
|
||||
|
||||
public void giveReputationToSenior(int gain, boolean includeSuperSenior) {
|
||||
int actualGain = gain;
|
||||
FamilyEntry senior = getSenior();
|
||||
if (senior != null && senior.getLevel() < getLevel() && gain > 0) {
|
||||
actualGain /= 2; //don't halve negative values
|
||||
}
|
||||
if (senior != null) {
|
||||
senior.gainReputation(actualGain, true, this);
|
||||
if (actualGain > 0) {
|
||||
this.repsToSenior += actualGain;
|
||||
this.repChanged = true;
|
||||
}
|
||||
if (includeSuperSenior) {
|
||||
senior = senior.getSenior();
|
||||
if (senior != null) {
|
||||
senior.gainReputation(actualGain, true, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalReputation() {
|
||||
return totalReputation;
|
||||
}
|
||||
|
||||
public void setTotalReputation(int totalReputation) {
|
||||
if (totalReputation != this.totalReputation) {
|
||||
this.repChanged = true;
|
||||
}
|
||||
this.totalReputation = totalReputation;
|
||||
}
|
||||
|
||||
public FamilyEntry getSenior() {
|
||||
return senior;
|
||||
}
|
||||
|
||||
public synchronized boolean setSenior(FamilyEntry senior, boolean save) {
|
||||
if (this.senior == senior) {
|
||||
return false;
|
||||
}
|
||||
FamilyEntry oldSenior = this.senior;
|
||||
this.senior = senior;
|
||||
if (senior != null) {
|
||||
if (senior.addJunior(this)) {
|
||||
if (save) {
|
||||
updateDBChangeFamily(getChrId(), senior.getFamily().getID(), senior.getChrId());
|
||||
}
|
||||
if (this.repsToSenior != 0) {
|
||||
this.repChanged = true;
|
||||
}
|
||||
this.repsToSenior = 0;
|
||||
this.addSeniorCount(1, null);
|
||||
this.setTotalSeniors(senior.getTotalSeniors() + 1);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (oldSenior != null) {
|
||||
oldSenior.removeJunior(this);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean updateDBChangeFamily(int cid, int familyid, int seniorid) {
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
return updateDBChangeFamily(con, cid, familyid, seniorid);
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not get connection to DB while changing family", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean updateDBChangeFamily(Connection con, int cid, int familyid, int seniorid) {
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE family_character SET familyid = ?, seniorid = ?, reptosenior = 0 WHERE cid = ?")) {
|
||||
ps.setInt(1, familyid);
|
||||
ps.setInt(2, seniorid);
|
||||
ps.setInt(3, cid);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not update seniorId in 'family_character' for chrId {}", cid, e);
|
||||
return false;
|
||||
}
|
||||
return updateCharacterFamilyDB(con, cid, familyid, false);
|
||||
}
|
||||
|
||||
private static boolean updateCharacterFamilyDB(Connection con, int charid, int familyid, boolean fork) {
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET familyid = ? WHERE id = ?")) {
|
||||
ps.setInt(1, familyid);
|
||||
ps.setInt(2, charid);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not update familyId in 'characters' for chrId {} when changing family. {}", charid, fork ? "(fork)" : "", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<FamilyEntry> getJuniors() {
|
||||
return Collections.unmodifiableList(Arrays.asList(juniors));
|
||||
}
|
||||
|
||||
public FamilyEntry getOtherJunior(FamilyEntry junior) {
|
||||
if (juniors[0] == junior) {
|
||||
return juniors[1];
|
||||
} else if (juniors[1] == junior) {
|
||||
return juniors[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getJuniorCount() { //close enough to be relatively consistent to multiple threads (and the result is not vital)
|
||||
int juniorCount = 0;
|
||||
if (juniors[0] != null) {
|
||||
juniorCount++;
|
||||
}
|
||||
if (juniors[1] != null) {
|
||||
juniorCount++;
|
||||
}
|
||||
return juniorCount;
|
||||
}
|
||||
|
||||
public synchronized boolean addJunior(FamilyEntry newJunior) {
|
||||
for (int i = 0; i < juniors.length; i++) {
|
||||
if (juniors[i] == null) { // successfully add new junior to family
|
||||
juniors[i] = newJunior;
|
||||
addJuniorCount(1);
|
||||
getFamily().addEntry(newJunior);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized boolean isJunior(FamilyEntry entry) { //require locking since result accuracy is vital
|
||||
if (juniors[0] == entry) {
|
||||
return true;
|
||||
} else {
|
||||
return juniors[1] == entry;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean removeJunior(FamilyEntry junior) {
|
||||
for (int i = 0; i < juniors.length; i++) {
|
||||
if (juniors[i] == junior) {
|
||||
juniors[i] = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getTotalSeniors() {
|
||||
return totalSeniors;
|
||||
}
|
||||
|
||||
public void setTotalSeniors(int totalSeniors) {
|
||||
this.totalSeniors = totalSeniors;
|
||||
}
|
||||
|
||||
public int getTotalJuniors() {
|
||||
return totalJuniors;
|
||||
}
|
||||
|
||||
public void setTotalJuniors(int totalJuniors) {
|
||||
this.totalJuniors = totalJuniors;
|
||||
}
|
||||
|
||||
public void announceToSenior(Packet packet, boolean includeSuperSenior) {
|
||||
FamilyEntry senior = getSenior();
|
||||
if (senior != null) {
|
||||
Character seniorChr = senior.getChr();
|
||||
if (seniorChr != null) {
|
||||
seniorChr.sendPacket(packet);
|
||||
}
|
||||
senior = senior.getSenior();
|
||||
if (includeSuperSenior && senior != null) {
|
||||
seniorChr = senior.getChr();
|
||||
if (seniorChr != null) {
|
||||
seniorChr.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSeniorFamilyInfo(boolean includeSuperSenior) {
|
||||
FamilyEntry senior = getSenior();
|
||||
if (senior != null) {
|
||||
Character seniorChr = senior.getChr();
|
||||
if (seniorChr != null) {
|
||||
seniorChr.sendPacket(PacketCreator.getFamilyInfo(senior));
|
||||
}
|
||||
senior = senior.getSenior();
|
||||
if (includeSuperSenior && senior != null) {
|
||||
seniorChr = senior.getChr();
|
||||
if (seniorChr != null) {
|
||||
seniorChr.sendPacket(PacketCreator.getFamilyInfo(senior));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses entire family tree to update senior/junior counts. Call on leader.
|
||||
*/
|
||||
public synchronized void doFullCount() {
|
||||
Pair<Integer, Integer> counts = this.traverseAndUpdateCounts(0);
|
||||
getFamily().setTotalGenerations(counts.getLeft() + 1);
|
||||
}
|
||||
|
||||
private Pair<Integer, Integer> traverseAndUpdateCounts(int seniors) { // recursion probably limits family size, but it should handle a depth of a few thousand
|
||||
setTotalSeniors(seniors);
|
||||
this.generation = seniors;
|
||||
int juniorCount = 0;
|
||||
int highestGeneration = this.generation;
|
||||
for (FamilyEntry entry : juniors) {
|
||||
if (entry != null) {
|
||||
Pair<Integer, Integer> counts = entry.traverseAndUpdateCounts(seniors + 1);
|
||||
juniorCount += counts.getRight(); //total juniors
|
||||
if (counts.getLeft() > highestGeneration) {
|
||||
highestGeneration = counts.getLeft();
|
||||
}
|
||||
}
|
||||
}
|
||||
setTotalJuniors(juniorCount);
|
||||
return new Pair<>(highestGeneration, juniorCount); //creating new objects to return is a bit inefficient, but cleaner than packing into a long
|
||||
}
|
||||
|
||||
public boolean useEntitlement(FamilyEntitlement entitlement) {
|
||||
int id = entitlement.ordinal();
|
||||
if (entitlements[id] >= 1) {
|
||||
return false;
|
||||
}
|
||||
try (Connection con = DatabaseConnection.getConnection(); PreparedStatement ps = con.prepareStatement("INSERT INTO family_entitlement (entitlementid, charid, timestamp) VALUES (?, ?, ?)")) {
|
||||
ps.setInt(1, id);
|
||||
ps.setInt(2, getChrId());
|
||||
ps.setLong(3, System.currentTimeMillis());
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not insert new row in 'family_entitlement' for chr {}", getName(), e);
|
||||
}
|
||||
entitlements[id]++;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean refundEntitlement(FamilyEntitlement entitlement) {
|
||||
int id = entitlement.ordinal();
|
||||
try (Connection con = DatabaseConnection.getConnection(); PreparedStatement ps = con.prepareStatement("DELETE FROM family_entitlement WHERE entitlementid = ? AND charid = ?")) {
|
||||
ps.setInt(1, id);
|
||||
ps.setInt(2, getChrId());
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not refund family entitlement \"{}\" for chr {}", entitlement.getName(), getName(), e);
|
||||
}
|
||||
entitlements[id] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isEntitlementUsed(FamilyEntitlement entitlement) {
|
||||
return entitlements[entitlement.ordinal()] >= 1;
|
||||
}
|
||||
|
||||
public int getEntitlementUsageCount(FamilyEntitlement entitlement) {
|
||||
return entitlements[entitlement.ordinal()];
|
||||
}
|
||||
|
||||
public void setEntitlementUsed(int id) {
|
||||
entitlements[id]++;
|
||||
}
|
||||
|
||||
public void resetEntitlementUsages() {
|
||||
for (FamilyEntitlement entitlement : FamilyEntitlement.values()) {
|
||||
entitlements[entitlement.ordinal()] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean saveReputation() {
|
||||
if (!repChanged) {
|
||||
return true;
|
||||
}
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
return saveReputation(con);
|
||||
} catch (SQLException e) {
|
||||
log.error("Could not get connection to DB while saving reputation", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean saveReputation(Connection con) {
|
||||
if (!repChanged) {
|
||||
return true;
|
||||
}
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE family_character SET reputation = ?, todaysrep = ?, totalreputation = ?, reptosenior = ? WHERE cid = ?")) {
|
||||
ps.setInt(1, getReputation());
|
||||
ps.setInt(2, getTodaysRep());
|
||||
ps.setInt(3, getTotalReputation());
|
||||
ps.setInt(4, getRepsToSenior());
|
||||
ps.setInt(5, getChrId());
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
log.error("Failed to autosave rep to 'family_character' for chrId {}", getChrId(), e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void savedSuccessfully() {
|
||||
this.repChanged = false;
|
||||
}
|
||||
}
|
||||
135
src/main/java/client/Job.java
Normal file
135
src/main/java/client/Job.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
public enum Job {
|
||||
BEGINNER(0),
|
||||
|
||||
WARRIOR(100),
|
||||
FIGHTER(110), CRUSADER(111), HERO(112),
|
||||
PAGE(120), WHITEKNIGHT(121), PALADIN(122),
|
||||
SPEARMAN(130), DRAGONKNIGHT(131), DARKKNIGHT(132),
|
||||
|
||||
MAGICIAN(200),
|
||||
FP_WIZARD(210), FP_MAGE(211), FP_ARCHMAGE(212),
|
||||
IL_WIZARD(220), IL_MAGE(221), IL_ARCHMAGE(222),
|
||||
CLERIC(230), PRIEST(231), BISHOP(232),
|
||||
|
||||
BOWMAN(300),
|
||||
HUNTER(310), RANGER(311), BOWMASTER(312),
|
||||
CROSSBOWMAN(320), SNIPER(321), MARKSMAN(322),
|
||||
|
||||
THIEF(400),
|
||||
ASSASSIN(410), HERMIT(411), NIGHTLORD(412),
|
||||
BANDIT(420), CHIEFBANDIT(421), SHADOWER(422),
|
||||
|
||||
PIRATE(500),
|
||||
BRAWLER(510), MARAUDER(511), BUCCANEER(512),
|
||||
GUNSLINGER(520), OUTLAW(521), CORSAIR(522),
|
||||
|
||||
MAPLELEAF_BRIGADIER(800),
|
||||
GM(900), SUPERGM(910),
|
||||
|
||||
NOBLESSE(1000),
|
||||
DAWNWARRIOR1(1100), DAWNWARRIOR2(1110), DAWNWARRIOR3(1111), DAWNWARRIOR4(1112),
|
||||
BLAZEWIZARD1(1200), BLAZEWIZARD2(1210), BLAZEWIZARD3(1211), BLAZEWIZARD4(1212),
|
||||
WINDARCHER1(1300), WINDARCHER2(1310), WINDARCHER3(1311), WINDARCHER4(1312),
|
||||
NIGHTWALKER1(1400), NIGHTWALKER2(1410), NIGHTWALKER3(1411), NIGHTWALKER4(1412),
|
||||
THUNDERBREAKER1(1500), THUNDERBREAKER2(1510), THUNDERBREAKER3(1511), THUNDERBREAKER4(1512),
|
||||
|
||||
LEGEND(2000), EVAN(2001),
|
||||
ARAN1(2100), ARAN2(2110), ARAN3(2111), ARAN4(2112),
|
||||
|
||||
EVAN1(2200), EVAN2(2210), EVAN3(2211), EVAN4(2212), EVAN5(2213), EVAN6(2214),
|
||||
EVAN7(2215), EVAN8(2216), EVAN9(2217), EVAN10(2218);
|
||||
|
||||
final int jobid;
|
||||
final static int maxId = 22; // maxId = (EVAN / 100);
|
||||
|
||||
Job(int id) {
|
||||
jobid = id;
|
||||
}
|
||||
|
||||
public static int getMax() {
|
||||
return maxId;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return jobid;
|
||||
}
|
||||
|
||||
public static Job getById(int id) {
|
||||
for (Job l : Job.values()) {
|
||||
if (l.getId() == id) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Job getBy5ByteEncoding(int encoded) {
|
||||
switch (encoded) {
|
||||
case 2:
|
||||
return WARRIOR;
|
||||
case 4:
|
||||
return MAGICIAN;
|
||||
case 8:
|
||||
return BOWMAN;
|
||||
case 16:
|
||||
return THIEF;
|
||||
case 32:
|
||||
return PIRATE;
|
||||
case 1024:
|
||||
return NOBLESSE;
|
||||
case 2048:
|
||||
return DAWNWARRIOR1;
|
||||
case 4096:
|
||||
return BLAZEWIZARD1;
|
||||
case 8192:
|
||||
return WINDARCHER1;
|
||||
case 16384:
|
||||
return NIGHTWALKER1;
|
||||
case 32768:
|
||||
return THUNDERBREAKER1;
|
||||
default:
|
||||
return BEGINNER;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isA(Job basejob) { // thanks Steve (kaito1410) for pointing out an improvement here
|
||||
int basebranch = basejob.getId() / 10;
|
||||
return (getId() / 10 == basebranch && getId() >= basejob.getId()) || (basebranch % 10 == 0 && getId() / 100 == basejob.getId() / 100);
|
||||
}
|
||||
|
||||
public int getJobNiche() {
|
||||
return (jobid / 100) % 10;
|
||||
|
||||
/*
|
||||
case 0: BEGINNER;
|
||||
case 1: WARRIOR;
|
||||
case 2: MAGICIAN;
|
||||
case 3: BOWMAN;
|
||||
case 4: THIEF;
|
||||
case 5: PIRATE;
|
||||
*/
|
||||
}
|
||||
}
|
||||
221
src/main/java/client/MonsterBook.java
Normal file
221
src/main/java/client/MonsterBook.java
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
import tools.DatabaseConnection;
|
||||
import tools.PacketCreator;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public final class MonsterBook {
|
||||
private int specialCard = 0;
|
||||
private int normalCard = 0;
|
||||
private int bookLevel = 1;
|
||||
private final Map<Integer, Integer> cards = new LinkedHashMap<>();
|
||||
private final Lock lock = new ReentrantLock();
|
||||
|
||||
public Set<Entry<Integer, Integer>> getCardSet() {
|
||||
lock.lock();
|
||||
try {
|
||||
return new HashSet<>(cards.entrySet());
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void addCard(final Client c, final int cardid) {
|
||||
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), PacketCreator.showForeignCardEffect(c.getPlayer().getId()), false);
|
||||
|
||||
Integer qty;
|
||||
lock.lock();
|
||||
try {
|
||||
qty = cards.get(cardid);
|
||||
|
||||
if (qty != null) {
|
||||
if (qty < 5) {
|
||||
cards.put(cardid, qty + 1);
|
||||
}
|
||||
} else {
|
||||
cards.put(cardid, 1);
|
||||
qty = 0;
|
||||
|
||||
if (cardid / 1000 >= 2388) {
|
||||
specialCard++;
|
||||
} else {
|
||||
normalCard++;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
if (qty < 5) {
|
||||
if (qty == 0) { // leveling system only accounts unique cards
|
||||
calculateLevel();
|
||||
}
|
||||
|
||||
c.sendPacket(PacketCreator.addCard(false, cardid, qty + 1));
|
||||
c.sendPacket(PacketCreator.showGainCard());
|
||||
} else {
|
||||
c.sendPacket(PacketCreator.addCard(true, cardid, 5));
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateLevel() {
|
||||
lock.lock();
|
||||
try {
|
||||
int collectionExp = (normalCard + specialCard);
|
||||
|
||||
int level = 0, expToNextlevel = 1;
|
||||
do {
|
||||
level++;
|
||||
expToNextlevel += level * 10;
|
||||
} while (collectionExp >= expToNextlevel);
|
||||
|
||||
bookLevel = level; // thanks IxianMace for noticing book level differing between book UI and character info UI
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getBookLevel() {
|
||||
lock.lock();
|
||||
try {
|
||||
return bookLevel;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getCards() {
|
||||
lock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableMap(cards);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalCards() {
|
||||
lock.lock();
|
||||
try {
|
||||
return specialCard + normalCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getNormalCard() {
|
||||
lock.lock();
|
||||
try {
|
||||
return normalCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getSpecialCard() {
|
||||
lock.lock();
|
||||
try {
|
||||
return specialCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadCards(final int charid) throws SQLException {
|
||||
lock.lock();
|
||||
try (Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT cardid, level FROM monsterbook WHERE charid = ? ORDER BY cardid ASC")) {
|
||||
ps.setInt(1, charid);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
int cardid;
|
||||
int level;
|
||||
while (rs.next()) {
|
||||
cardid = rs.getInt("cardid");
|
||||
level = rs.getInt("level");
|
||||
if (cardid / 1000 >= 2388) {
|
||||
specialCard++;
|
||||
} else {
|
||||
normalCard++;
|
||||
}
|
||||
cards.put(cardid, level);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
calculateLevel();
|
||||
}
|
||||
|
||||
public void saveCards(Connection con, int chrId) throws SQLException {
|
||||
final String query = """
|
||||
INSERT INTO monsterbook (charid, cardid, level)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE level = ?;
|
||||
""";
|
||||
try (final PreparedStatement ps = con.prepareStatement(query)) {
|
||||
for (Map.Entry<Integer, Integer> cardAndLevel : cards.entrySet()) {
|
||||
final int card = cardAndLevel.getKey();
|
||||
final int level = cardAndLevel.getValue();
|
||||
// insert
|
||||
ps.setInt(1, chrId);
|
||||
ps.setInt(2, card);
|
||||
ps.setInt(3, level);
|
||||
|
||||
// update
|
||||
ps.setInt(4, level);
|
||||
|
||||
ps.addBatch();
|
||||
}
|
||||
ps.executeBatch();
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] getCardTierSize() {
|
||||
try (Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) FROM monstercarddata GROUP BY floor(cardid / 1000);", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet rs = ps.executeQuery()) {
|
||||
rs.last();
|
||||
int[] tierSizes = new int[rs.getRow()];
|
||||
rs.beforeFirst();
|
||||
|
||||
while (rs.next()) {
|
||||
tierSizes[rs.getRow() - 1] = rs.getInt(1);
|
||||
}
|
||||
|
||||
return tierSizes;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return new int[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
130
src/main/java/client/Mount.java
Normal file
130
src/main/java/client/Mount.java
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
/**
|
||||
* @author PurpleMadness < Patrick :O >
|
||||
*/
|
||||
public class Mount {
|
||||
private int itemid;
|
||||
private int skillid;
|
||||
private int tiredness;
|
||||
private int exp;
|
||||
private int level;
|
||||
private Character owner;
|
||||
private boolean active;
|
||||
|
||||
public Mount(Character owner, int id, int skillid) {
|
||||
this.itemid = id;
|
||||
this.skillid = skillid;
|
||||
this.tiredness = 0;
|
||||
this.level = 1;
|
||||
this.exp = 0;
|
||||
this.owner = owner;
|
||||
active = true;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return itemid;
|
||||
}
|
||||
|
||||
public int getSkillId() {
|
||||
return skillid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1902000 - Hog
|
||||
* 1902001 - Silver Mane
|
||||
* 1902002 - Red Draco
|
||||
* 1902005 - Mimiana
|
||||
* 1902006 - Mimio
|
||||
* 1902007 - Shinjou
|
||||
* 1902008 - Frog
|
||||
* 1902009 - Ostrich
|
||||
* 1902010 - Frog
|
||||
* 1902011 - Turtle
|
||||
* 1902012 - Yeti
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public int getId() {
|
||||
if (this.itemid < 1903000) {
|
||||
return itemid - 1901999;
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
|
||||
public int getTiredness() {
|
||||
return tiredness;
|
||||
}
|
||||
|
||||
public int getExp() {
|
||||
return exp;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setTiredness(int newtiredness) {
|
||||
this.tiredness = newtiredness;
|
||||
if (tiredness < 0) {
|
||||
tiredness = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int incrementAndGetTiredness() {
|
||||
this.tiredness++;
|
||||
return this.tiredness;
|
||||
}
|
||||
|
||||
public void setExp(int newexp) {
|
||||
this.exp = newexp;
|
||||
}
|
||||
|
||||
public void setLevel(int newlevel) {
|
||||
this.level = newlevel;
|
||||
}
|
||||
|
||||
public void setItemId(int newitemid) {
|
||||
this.itemid = newitemid;
|
||||
}
|
||||
|
||||
public void setSkillId(int newskillid) {
|
||||
this.skillid = newskillid;
|
||||
}
|
||||
|
||||
public void setActive(boolean set) {
|
||||
this.active = set;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void empty() {
|
||||
if (owner != null) {
|
||||
owner.getClient().getWorldServer().unregisterMountHunger(owner);
|
||||
}
|
||||
this.owner = null;
|
||||
}
|
||||
}
|
||||
278
src/main/java/client/QuestStatus.java
Normal file
278
src/main/java/client/QuestStatus.java
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
import server.quest.Quest;
|
||||
import tools.StringUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Matze
|
||||
*/
|
||||
public class QuestStatus {
|
||||
public enum Status {
|
||||
UNDEFINED(-1),
|
||||
NOT_STARTED(0),
|
||||
STARTED(1),
|
||||
COMPLETED(2);
|
||||
final int status;
|
||||
|
||||
Status(int id) {
|
||||
status = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public static Status getById(int id) {
|
||||
for (Status l : Status.values()) {
|
||||
if (l.getId() == id) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final short questID;
|
||||
private Status status;
|
||||
//private boolean updated; //maybe this can be of use for someone?
|
||||
private final Map<Integer, String> progress = new LinkedHashMap<>();
|
||||
private final List<Integer> medalProgress = new LinkedList<>();
|
||||
private int npc;
|
||||
private long completionTime, expirationTime;
|
||||
private int forfeited = 0, completed = 0;
|
||||
private String customData;
|
||||
|
||||
public QuestStatus(Quest quest, Status status) {
|
||||
this.questID = quest.getId();
|
||||
this.setStatus(status);
|
||||
this.completionTime = System.currentTimeMillis();
|
||||
this.expirationTime = 0;
|
||||
//this.updated = true;
|
||||
if (status == Status.STARTED) {
|
||||
registerMobs();
|
||||
}
|
||||
}
|
||||
|
||||
public QuestStatus(Quest quest, Status status, int npc) {
|
||||
this.questID = quest.getId();
|
||||
this.setStatus(status);
|
||||
this.setNpc(npc);
|
||||
this.completionTime = System.currentTimeMillis();
|
||||
this.expirationTime = 0;
|
||||
//this.updated = true;
|
||||
if (status == Status.STARTED) {
|
||||
registerMobs();
|
||||
}
|
||||
}
|
||||
|
||||
public Quest getQuest() {
|
||||
return Quest.getInstance(questID);
|
||||
}
|
||||
|
||||
public short getQuestID() {
|
||||
return questID;
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public final void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/*
|
||||
public boolean wasUpdated() {
|
||||
return updated;
|
||||
}
|
||||
|
||||
private void setUpdated() {
|
||||
this.updated = true;
|
||||
}
|
||||
|
||||
public void resetUpdated() {
|
||||
this.updated = false;
|
||||
}
|
||||
*/
|
||||
|
||||
public int getNpc() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
public final void setNpc(int npc) {
|
||||
this.npc = npc;
|
||||
}
|
||||
|
||||
private void registerMobs() {
|
||||
for (int i : Quest.getInstance(questID).getRelevantMobs()) {
|
||||
progress.put(i, "000");
|
||||
}
|
||||
//this.setUpdated();
|
||||
}
|
||||
|
||||
public boolean addMedalMap(int mapid) {
|
||||
if (medalProgress.contains(mapid)) {
|
||||
return false;
|
||||
}
|
||||
medalProgress.add(mapid);
|
||||
//this.setUpdated();
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getMedalProgress() {
|
||||
return medalProgress.size();
|
||||
}
|
||||
|
||||
public List<Integer> getMedalMaps() {
|
||||
return medalProgress;
|
||||
}
|
||||
|
||||
public boolean progress(int id) {
|
||||
String currentStr = progress.get(id);
|
||||
if (currentStr == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int current = Integer.parseInt(currentStr);
|
||||
if (current >= this.getQuest().getMobAmountNeeded(id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String str = StringUtil.getLeftPaddedStr(Integer.toString(++current), '0', 3);
|
||||
progress.put(id, str);
|
||||
//this.setUpdated();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setProgress(int id, String pr) {
|
||||
progress.put(id, pr);
|
||||
//this.setUpdated();
|
||||
}
|
||||
|
||||
public boolean madeProgress() {
|
||||
return progress.size() > 0;
|
||||
}
|
||||
|
||||
public String getProgress(int id) {
|
||||
String ret = progress.get(id);
|
||||
if (ret == null) {
|
||||
return "";
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public void resetProgress(int id) {
|
||||
setProgress(id, "000");
|
||||
}
|
||||
|
||||
public void resetAllProgress() {
|
||||
for (Map.Entry<Integer, String> entry : progress.entrySet()) {
|
||||
setProgress(entry.getKey(), "000");
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, String> getProgress() {
|
||||
return Collections.unmodifiableMap(progress);
|
||||
}
|
||||
|
||||
public short getInfoNumber() {
|
||||
Quest q = this.getQuest();
|
||||
Status s = this.getStatus();
|
||||
|
||||
return q.getInfoNumber(s);
|
||||
}
|
||||
|
||||
public String getInfoEx(int index) {
|
||||
Quest q = this.getQuest();
|
||||
Status s = this.getStatus();
|
||||
|
||||
return q.getInfoEx(s, index);
|
||||
}
|
||||
|
||||
public List<String> getInfoEx() {
|
||||
Quest q = this.getQuest();
|
||||
Status s = this.getStatus();
|
||||
|
||||
return q.getInfoEx(s);
|
||||
}
|
||||
|
||||
public long getCompletionTime() {
|
||||
return completionTime;
|
||||
}
|
||||
|
||||
public void setCompletionTime(long completionTime) {
|
||||
this.completionTime = completionTime;
|
||||
}
|
||||
|
||||
public long getExpirationTime() {
|
||||
return expirationTime;
|
||||
}
|
||||
|
||||
public void setExpirationTime(long expirationTime) {
|
||||
this.expirationTime = expirationTime;
|
||||
}
|
||||
|
||||
public int getForfeited() {
|
||||
return forfeited;
|
||||
}
|
||||
|
||||
public int getCompleted() {
|
||||
return completed;
|
||||
}
|
||||
|
||||
public void setForfeited(int forfeited) {
|
||||
if (forfeited >= this.forfeited) {
|
||||
this.forfeited = forfeited;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can't set forfeits to something lower than before.");
|
||||
}
|
||||
}
|
||||
|
||||
public void setCompleted(int completed) {
|
||||
if (completed >= this.completed) {
|
||||
this.completed = completed;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can't set completes to something lower than before.");
|
||||
}
|
||||
}
|
||||
|
||||
public final void setCustomData(final String customData) {
|
||||
this.customData = customData;
|
||||
}
|
||||
|
||||
public final String getCustomData() {
|
||||
return customData;
|
||||
}
|
||||
|
||||
public String getProgressData() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
for (String ps : progress.values()) {
|
||||
str.append(ps);
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
199
src/main/java/client/Ring.java
Normal file
199
src/main/java/client/Ring.java
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
import client.inventory.manipulator.CashIdGenerator;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.Pair;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @author Danny
|
||||
*/
|
||||
public class Ring implements Comparable<Ring> {
|
||||
private final int ringId;
|
||||
private final int ringId2;
|
||||
private final int partnerId;
|
||||
private final int itemId;
|
||||
private final String partnerName;
|
||||
private boolean equipped = false;
|
||||
|
||||
public Ring(int id, int id2, int partnerId, int itemid, String partnername) {
|
||||
this.ringId = id;
|
||||
this.ringId2 = id2;
|
||||
this.partnerId = partnerId;
|
||||
this.itemId = itemid;
|
||||
this.partnerName = partnername;
|
||||
}
|
||||
|
||||
public static Ring loadFromDb(int ringId) {
|
||||
Ring ret = null;
|
||||
try (Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT * FROM rings WHERE id = ?")) {
|
||||
ps.setInt(1, ringId);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
ret = new Ring(ringId, rs.getInt("partnerRingId"), rs.getInt("partnerChrId"), rs.getInt("itemid"), rs.getString("partnerName"));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeRing(final Ring ring) {
|
||||
try {
|
||||
if (ring == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("DELETE FROM rings WHERE id=?")) {
|
||||
ps.setInt(1, ring.getRingId());
|
||||
ps.addBatch();
|
||||
|
||||
ps.setInt(1, ring.getPartnerRingId());
|
||||
ps.addBatch();
|
||||
|
||||
ps.executeBatch();
|
||||
}
|
||||
|
||||
CashIdGenerator.freeCashId(ring.getRingId());
|
||||
CashIdGenerator.freeCashId(ring.getPartnerRingId());
|
||||
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE inventoryequipment SET ringid=-1 WHERE ringid=?")) {
|
||||
ps.setInt(1, ring.getRingId());
|
||||
ps.addBatch();
|
||||
|
||||
ps.setInt(1, ring.getPartnerRingId());
|
||||
ps.addBatch();
|
||||
|
||||
ps.executeBatch();
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Pair<Integer, Integer> createRing(int itemid, final Character partner1, final Character partner2) {
|
||||
try {
|
||||
if (partner1 == null) {
|
||||
return new Pair<>(-3, -3);
|
||||
} else if (partner2 == null) {
|
||||
return new Pair<>(-2, -2);
|
||||
}
|
||||
|
||||
int[] ringID = new int[2];
|
||||
ringID[0] = CashIdGenerator.generateCashId();
|
||||
ringID[1] = CashIdGenerator.generateCashId();
|
||||
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("INSERT INTO rings (id, itemid, partnerRingId, partnerChrId, partnername) VALUES (?, ?, ?, ?, ?)")) {
|
||||
ps.setInt(1, ringID[0]);
|
||||
ps.setInt(2, itemid);
|
||||
ps.setInt(3, ringID[1]);
|
||||
ps.setInt(4, partner2.getId());
|
||||
ps.setString(5, partner2.getName());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
|
||||
try (PreparedStatement ps = con.prepareStatement("INSERT INTO rings (id, itemid, partnerRingId, partnerChrId, partnername) VALUES (?, ?, ?, ?, ?)")) {
|
||||
ps.setInt(1, ringID[1]);
|
||||
ps.setInt(2, itemid);
|
||||
ps.setInt(3, ringID[0]);
|
||||
ps.setInt(4, partner1.getId());
|
||||
ps.setString(5, partner1.getName());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
}
|
||||
return new Pair<>(ringID[0], ringID[1]);
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
return new Pair<>(-1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public int getRingId() {
|
||||
return ringId;
|
||||
}
|
||||
|
||||
public int getPartnerRingId() {
|
||||
return ringId2;
|
||||
}
|
||||
|
||||
public int getPartnerChrId() {
|
||||
return partnerId;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public String getPartnerName() {
|
||||
return partnerName;
|
||||
}
|
||||
|
||||
public boolean equipped() {
|
||||
return equipped;
|
||||
}
|
||||
|
||||
public void equip() {
|
||||
this.equipped = true;
|
||||
}
|
||||
|
||||
public void unequip() {
|
||||
this.equipped = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Ring ring) {
|
||||
return ring.getRingId() == getRingId();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 53 * hash + this.ringId;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Ring other) {
|
||||
if (ringId < other.getRingId()) {
|
||||
return -1;
|
||||
} else if (ringId == other.getRingId()) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
100
src/main/java/client/Skill.java
Normal file
100
src/main/java/client/Skill.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
import server.StatEffect;
|
||||
import server.life.Element;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Skill {
|
||||
private final int id;
|
||||
private final List<StatEffect> effects = new ArrayList<>();
|
||||
private Element element;
|
||||
private int animationTime;
|
||||
private final int job;
|
||||
private boolean action;
|
||||
|
||||
public Skill(int id) {
|
||||
this.id = id;
|
||||
this.job = id / 10000;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public StatEffect getEffect(int level) {
|
||||
return effects.get(level - 1);
|
||||
}
|
||||
|
||||
public int getMaxLevel() {
|
||||
return effects.size();
|
||||
}
|
||||
|
||||
public boolean isFourthJob() {
|
||||
if (job == 2212) {
|
||||
return false;
|
||||
}
|
||||
if (id == 22170001 || id == 22171003 || id == 22171004 || id == 22181002 || id == 22181003) {
|
||||
return true;
|
||||
}
|
||||
return job % 10 == 2;
|
||||
}
|
||||
|
||||
public void setElement(Element elem) {
|
||||
element = elem;
|
||||
}
|
||||
|
||||
public Element getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public int getAnimationTime() {
|
||||
return animationTime;
|
||||
}
|
||||
|
||||
public void setAnimationTime(int time) {
|
||||
animationTime = time;
|
||||
}
|
||||
|
||||
public void incAnimationTime(int time) {
|
||||
animationTime += time;
|
||||
}
|
||||
|
||||
public boolean isBeginnerSkill() {
|
||||
return id % 10000000 < 10000;
|
||||
}
|
||||
|
||||
public void setAction(boolean act) {
|
||||
action = act;
|
||||
}
|
||||
|
||||
public boolean getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public void addLevelEffect(StatEffect effect) {
|
||||
effects.add(effect);
|
||||
}
|
||||
}
|
||||
350
src/main/java/client/SkillFactory.java
Normal file
350
src/main/java/client/SkillFactory.java
Normal file
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
import constants.skills.*;
|
||||
import provider.*;
|
||||
import provider.wz.WZFiles;
|
||||
import server.StatEffect;
|
||||
import server.life.Element;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SkillFactory {
|
||||
private static volatile Map<Integer, Skill> skills = new HashMap<>();
|
||||
private static final DataProvider datasource = DataProviderFactory.getDataProvider(WZFiles.SKILL);
|
||||
|
||||
public static Skill getSkill(int id) {
|
||||
return skills.get(id);
|
||||
}
|
||||
|
||||
public static void loadAllSkills() {
|
||||
final Map<Integer, Skill> loadedSkills = new HashMap<>();
|
||||
final DataDirectoryEntry root = datasource.getRoot();
|
||||
for (DataFileEntry topDir : root.getFiles()) { // Loop thru jobs
|
||||
if (topDir.getName().length() <= 8) {
|
||||
for (Data data : datasource.getData(topDir.getName())) { // Loop thru each jobs
|
||||
if (data.getName().equals("skill")) {
|
||||
for (Data data2 : data) { // Loop thru each jobs
|
||||
if (data2 != null) {
|
||||
int skillId = Integer.parseInt(data2.getName());
|
||||
loadedSkills.put(skillId, loadFromData(skillId, data2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
skills = loadedSkills;
|
||||
}
|
||||
|
||||
private static Skill loadFromData(int id, Data data) {
|
||||
Skill ret = new Skill(id);
|
||||
boolean isBuff = false;
|
||||
int skillType = DataTool.getInt("skillType", data, -1);
|
||||
String elem = DataTool.getString("elemAttr", data, null);
|
||||
if (elem != null) {
|
||||
ret.setElement(Element.getFromChar(elem.charAt(0)));
|
||||
} else {
|
||||
ret.setElement(Element.NEUTRAL);
|
||||
}
|
||||
Data effect = data.getChildByPath("effect");
|
||||
if (skillType != -1) {
|
||||
if (skillType == 2) {
|
||||
isBuff = true;
|
||||
}
|
||||
} else {
|
||||
Data action_ = data.getChildByPath("action");
|
||||
boolean action = false;
|
||||
if (action_ == null) {
|
||||
if (data.getChildByPath("prepare/action") != null) {
|
||||
action = true;
|
||||
} else {
|
||||
switch (id) {
|
||||
case Gunslinger.INVISIBLE_SHOT:
|
||||
case Corsair.HYPNOTIZE:
|
||||
action = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
action = true;
|
||||
}
|
||||
ret.setAction(action);
|
||||
Data hit = data.getChildByPath("hit");
|
||||
Data ball = data.getChildByPath("ball");
|
||||
isBuff = effect != null && hit == null && ball == null;
|
||||
isBuff |= action_ != null && DataTool.getString("0", action_, "").equals("alert2");
|
||||
switch (id) {
|
||||
case Hero.RUSH:
|
||||
case Paladin.RUSH:
|
||||
case DarkKnight.RUSH:
|
||||
case DragonKnight.SACRIFICE:
|
||||
case FPMage.EXPLOSION:
|
||||
case FPMage.POISON_MIST:
|
||||
case Cleric.HEAL:
|
||||
case Ranger.MORTAL_BLOW:
|
||||
case Sniper.MORTAL_BLOW:
|
||||
case Assassin.DRAIN:
|
||||
case Hermit.SHADOW_WEB:
|
||||
case Bandit.STEAL:
|
||||
case Shadower.SMOKE_SCREEN:
|
||||
case SuperGM.HEAL_PLUS_DISPEL:
|
||||
case Hero.MONSTER_MAGNET:
|
||||
case Paladin.MONSTER_MAGNET:
|
||||
case DarkKnight.MONSTER_MAGNET:
|
||||
case Evan.ICE_BREATH:
|
||||
case Evan.FIRE_BREATH:
|
||||
case Gunslinger.RECOIL_SHOT:
|
||||
case Marauder.ENERGY_DRAIN:
|
||||
case BlazeWizard.FLAME_GEAR:
|
||||
case NightWalker.SHADOW_WEB:
|
||||
case NightWalker.POISON_BOMB:
|
||||
case NightWalker.VAMPIRE:
|
||||
case ChiefBandit.CHAKRA:
|
||||
case Aran.COMBAT_STEP:
|
||||
case Evan.RECOVERY_AURA:
|
||||
isBuff = false;
|
||||
break;
|
||||
case Beginner.RECOVERY:
|
||||
case Beginner.NIMBLE_FEET:
|
||||
case Beginner.MONSTER_RIDER:
|
||||
case Beginner.ECHO_OF_HERO:
|
||||
case Beginner.MAP_CHAIR:
|
||||
case Warrior.IRON_BODY:
|
||||
case Fighter.AXE_BOOSTER:
|
||||
case Fighter.POWER_GUARD:
|
||||
case Fighter.RAGE:
|
||||
case Fighter.SWORD_BOOSTER:
|
||||
case Crusader.ARMOR_CRASH:
|
||||
case Crusader.COMBO:
|
||||
case Hero.ENRAGE:
|
||||
case Hero.HEROS_WILL:
|
||||
case Hero.MAPLE_WARRIOR:
|
||||
case Hero.STANCE:
|
||||
case Page.BW_BOOSTER:
|
||||
case Page.POWER_GUARD:
|
||||
case Page.SWORD_BOOSTER:
|
||||
case Page.THREATEN:
|
||||
case WhiteKnight.BW_FIRE_CHARGE:
|
||||
case WhiteKnight.BW_ICE_CHARGE:
|
||||
case WhiteKnight.BW_LIT_CHARGE:
|
||||
case WhiteKnight.MAGIC_CRASH:
|
||||
case WhiteKnight.SWORD_FIRE_CHARGE:
|
||||
case WhiteKnight.SWORD_ICE_CHARGE:
|
||||
case WhiteKnight.SWORD_LIT_CHARGE:
|
||||
case Paladin.BW_HOLY_CHARGE:
|
||||
case Paladin.HEROS_WILL:
|
||||
case Paladin.MAPLE_WARRIOR:
|
||||
case Paladin.STANCE:
|
||||
case Paladin.SWORD_HOLY_CHARGE:
|
||||
case Spearman.HYPER_BODY:
|
||||
case Spearman.IRON_WILL:
|
||||
case Spearman.POLEARM_BOOSTER:
|
||||
case Spearman.SPEAR_BOOSTER:
|
||||
case DragonKnight.DRAGON_BLOOD:
|
||||
case DragonKnight.POWER_CRASH:
|
||||
case DarkKnight.AURA_OF_BEHOLDER:
|
||||
case DarkKnight.BEHOLDER:
|
||||
case DarkKnight.HEROS_WILL:
|
||||
case DarkKnight.HEX_OF_BEHOLDER:
|
||||
case DarkKnight.MAPLE_WARRIOR:
|
||||
case DarkKnight.STANCE:
|
||||
case Magician.MAGIC_GUARD:
|
||||
case Magician.MAGIC_ARMOR:
|
||||
case FPWizard.MEDITATION:
|
||||
case FPWizard.SLOW:
|
||||
case FPMage.SEAL:
|
||||
case FPMage.SPELL_BOOSTER:
|
||||
case FPArchMage.HEROS_WILL:
|
||||
case FPArchMage.INFINITY:
|
||||
case FPArchMage.MANA_REFLECTION:
|
||||
case FPArchMage.MAPLE_WARRIOR:
|
||||
case ILWizard.MEDITATION:
|
||||
case ILMage.SEAL:
|
||||
case ILWizard.SLOW:
|
||||
case ILMage.SPELL_BOOSTER:
|
||||
case ILArchMage.HEROS_WILL:
|
||||
case ILArchMage.INFINITY:
|
||||
case ILArchMage.MANA_REFLECTION:
|
||||
case ILArchMage.MAPLE_WARRIOR:
|
||||
case Cleric.INVINCIBLE:
|
||||
case Cleric.BLESS:
|
||||
case Priest.DISPEL:
|
||||
case Priest.DOOM:
|
||||
case Priest.HOLY_SYMBOL:
|
||||
case Priest.MYSTIC_DOOR:
|
||||
case Bishop.HEROS_WILL:
|
||||
case Bishop.HOLY_SHIELD:
|
||||
case Bishop.INFINITY:
|
||||
case Bishop.MANA_REFLECTION:
|
||||
case Bishop.MAPLE_WARRIOR:
|
||||
case Archer.FOCUS:
|
||||
case Hunter.BOW_BOOSTER:
|
||||
case Hunter.SOUL_ARROW:
|
||||
case Ranger.PUPPET:
|
||||
case Bowmaster.CONCENTRATE:
|
||||
case Bowmaster.HEROS_WILL:
|
||||
case Bowmaster.MAPLE_WARRIOR:
|
||||
case Bowmaster.SHARP_EYES:
|
||||
case Crossbowman.CROSSBOW_BOOSTER:
|
||||
case Crossbowman.SOUL_ARROW:
|
||||
case Sniper.PUPPET:
|
||||
case Marksman.BLIND:
|
||||
case Marksman.HEROS_WILL:
|
||||
case Marksman.MAPLE_WARRIOR:
|
||||
case Marksman.SHARP_EYES:
|
||||
case Rogue.DARK_SIGHT:
|
||||
case Assassin.CLAW_BOOSTER:
|
||||
case Assassin.HASTE:
|
||||
case Hermit.MESO_UP:
|
||||
case Hermit.SHADOW_PARTNER:
|
||||
case NightLord.HEROS_WILL:
|
||||
case NightLord.MAPLE_WARRIOR:
|
||||
case NightLord.NINJA_AMBUSH:
|
||||
case NightLord.SHADOW_STARS:
|
||||
case Bandit.DAGGER_BOOSTER:
|
||||
case Bandit.HASTE:
|
||||
case ChiefBandit.MESO_GUARD:
|
||||
case ChiefBandit.PICKPOCKET:
|
||||
case Shadower.HEROS_WILL:
|
||||
case Shadower.MAPLE_WARRIOR:
|
||||
case Shadower.NINJA_AMBUSH:
|
||||
case Pirate.DASH:
|
||||
case Marauder.TRANSFORMATION:
|
||||
case Buccaneer.SUPER_TRANSFORMATION:
|
||||
case Corsair.BATTLE_SHIP:
|
||||
case GM.HIDE:
|
||||
case SuperGM.HASTE:
|
||||
case SuperGM.HOLY_SYMBOL:
|
||||
case SuperGM.BLESS:
|
||||
case SuperGM.HIDE:
|
||||
case SuperGM.HYPER_BODY:
|
||||
case Noblesse.BLESSING_OF_THE_FAIRY:
|
||||
case Noblesse.ECHO_OF_HERO:
|
||||
case Noblesse.MONSTER_RIDER:
|
||||
case Noblesse.NIMBLE_FEET:
|
||||
case Noblesse.RECOVERY:
|
||||
case Noblesse.MAP_CHAIR:
|
||||
case DawnWarrior.COMBO:
|
||||
case DawnWarrior.FINAL_ATTACK:
|
||||
case DawnWarrior.IRON_BODY:
|
||||
case DawnWarrior.RAGE:
|
||||
case DawnWarrior.SOUL:
|
||||
case DawnWarrior.SOUL_CHARGE:
|
||||
case DawnWarrior.SWORD_BOOSTER:
|
||||
case BlazeWizard.ELEMENTAL_RESET:
|
||||
case BlazeWizard.FLAME:
|
||||
case BlazeWizard.IFRIT:
|
||||
case BlazeWizard.MAGIC_ARMOR:
|
||||
case BlazeWizard.MAGIC_GUARD:
|
||||
case BlazeWizard.MEDITATION:
|
||||
case BlazeWizard.SEAL:
|
||||
case BlazeWizard.SLOW:
|
||||
case BlazeWizard.SPELL_BOOSTER:
|
||||
case WindArcher.BOW_BOOSTER:
|
||||
case WindArcher.EAGLE_EYE:
|
||||
case WindArcher.FINAL_ATTACK:
|
||||
case WindArcher.FOCUS:
|
||||
case WindArcher.PUPPET:
|
||||
case WindArcher.SOUL_ARROW:
|
||||
case WindArcher.STORM:
|
||||
case WindArcher.WIND_WALK:
|
||||
case NightWalker.CLAW_BOOSTER:
|
||||
case NightWalker.DARKNESS:
|
||||
case NightWalker.DARK_SIGHT:
|
||||
case NightWalker.HASTE:
|
||||
case NightWalker.SHADOW_PARTNER:
|
||||
case ThunderBreaker.DASH:
|
||||
case ThunderBreaker.ENERGY_CHARGE:
|
||||
case ThunderBreaker.ENERGY_DRAIN:
|
||||
case ThunderBreaker.KNUCKLER_BOOSTER:
|
||||
case ThunderBreaker.LIGHTNING:
|
||||
case ThunderBreaker.SPARK:
|
||||
case ThunderBreaker.LIGHTNING_CHARGE:
|
||||
case ThunderBreaker.SPEED_INFUSION:
|
||||
case ThunderBreaker.TRANSFORMATION:
|
||||
case Legend.BLESSING_OF_THE_FAIRY:
|
||||
case Legend.AGILE_BODY:
|
||||
case Legend.ECHO_OF_HERO:
|
||||
case Legend.RECOVERY:
|
||||
case Legend.MONSTER_RIDER:
|
||||
case Legend.MAP_CHAIR:
|
||||
case Aran.MAPLE_WARRIOR:
|
||||
case Aran.HEROS_WILL:
|
||||
case Aran.POLEARM_BOOSTER:
|
||||
case Aran.COMBO_DRAIN:
|
||||
case Aran.SNOW_CHARGE:
|
||||
case Aran.BODY_PRESSURE:
|
||||
case Aran.SMART_KNOCKBACK:
|
||||
case Aran.COMBO_BARRIER:
|
||||
case Aran.COMBO_ABILITY:
|
||||
case Evan.BLESSING_OF_THE_FAIRY:
|
||||
case Evan.RECOVERY:
|
||||
case Evan.NIMBLE_FEET:
|
||||
case Evan.HEROS_WILL:
|
||||
case Evan.ECHO_OF_HERO:
|
||||
case Evan.MAGIC_BOOSTER:
|
||||
case Evan.MAGIC_GUARD:
|
||||
case Evan.ELEMENTAL_RESET:
|
||||
case Evan.MAPLE_WARRIOR:
|
||||
case Evan.MAGIC_RESISTANCE:
|
||||
case Evan.MAGIC_SHIELD:
|
||||
case Evan.SLOW:
|
||||
isBuff = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (Data level : data.getChildByPath("level")) {
|
||||
ret.addLevelEffect(StatEffect.loadSkillEffectFromData(level, id, isBuff));
|
||||
}
|
||||
ret.setAnimationTime(0);
|
||||
if (effect != null) {
|
||||
for (Data effectEntry : effect) {
|
||||
ret.incAnimationTime(DataTool.getIntConvert("delay", effectEntry, 0));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String getSkillName(int skillid) {
|
||||
Data data = DataProviderFactory.getDataProvider(WZFiles.STRING).getData("Skill.img");
|
||||
StringBuilder skill = new StringBuilder();
|
||||
skill.append(skillid);
|
||||
if (skill.length() == 4) {
|
||||
skill.delete(0, 4);
|
||||
skill.append("000").append(skillid);
|
||||
}
|
||||
if (data.getChildByPath(skill.toString()) != null) {
|
||||
for (Data skilldata : data.getChildByPath(skill.toString()).getChildren()) {
|
||||
if (skilldata.getName().equals("name")) {
|
||||
return DataTool.getString(skilldata, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
76
src/main/java/client/SkillMacro.java
Normal file
76
src/main/java/client/SkillMacro.java
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
public class SkillMacro {
|
||||
private int skill1;
|
||||
private int skill2;
|
||||
private int skill3;
|
||||
private final String name;
|
||||
private final int shout;
|
||||
private final int position;
|
||||
|
||||
public SkillMacro(int skill1, int skill2, int skill3, String name, int shout, int position) {
|
||||
this.skill1 = skill1;
|
||||
this.skill2 = skill2;
|
||||
this.skill3 = skill3;
|
||||
this.name = name;
|
||||
this.shout = shout;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public int getSkill1() {
|
||||
return skill1;
|
||||
}
|
||||
|
||||
public int getSkill2() {
|
||||
return skill2;
|
||||
}
|
||||
|
||||
public int getSkill3() {
|
||||
return skill3;
|
||||
}
|
||||
|
||||
public void setSkill1(int skill) {
|
||||
skill1 = skill;
|
||||
}
|
||||
|
||||
public void setSkill2(int skill) {
|
||||
skill2 = skill;
|
||||
}
|
||||
|
||||
public void setSkill3(int skill) {
|
||||
skill3 = skill;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getShout() {
|
||||
return shout;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
52
src/main/java/client/SkinColor.java
Normal file
52
src/main/java/client/SkinColor.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 client;
|
||||
|
||||
public enum SkinColor {
|
||||
NORMAL(0),
|
||||
DARK(1),
|
||||
BLACK(2),
|
||||
PALE(3),
|
||||
BLUE(4),
|
||||
GREEN(5),
|
||||
WHITE(9),
|
||||
PINK(10);
|
||||
|
||||
final int id;
|
||||
|
||||
SkinColor(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public static SkinColor getById(int id) {
|
||||
for (SkinColor l : SkinColor.values()) {
|
||||
if (l.getId() == id) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
86
src/main/java/client/Stat.java
Normal file
86
src/main/java/client/Stat.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
public enum Stat {
|
||||
SKIN(0x1),
|
||||
FACE(0x2),
|
||||
HAIR(0x4),
|
||||
LEVEL(0x10),
|
||||
JOB(0x20),
|
||||
STR(0x40),
|
||||
DEX(0x80),
|
||||
INT(0x100),
|
||||
LUK(0x200),
|
||||
HP(0x400),
|
||||
MAXHP(0x800),
|
||||
MP(0x1000),
|
||||
MAXMP(0x2000),
|
||||
AVAILABLEAP(0x4000),
|
||||
AVAILABLESP(0x8000),
|
||||
EXP(0x10000),
|
||||
FAME(0x20000),
|
||||
MESO(0x40000),
|
||||
PET(0x180008),
|
||||
GACHAEXP(0x200000);
|
||||
private final int i;
|
||||
|
||||
Stat(int i) {
|
||||
this.i = i;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return i;
|
||||
}
|
||||
|
||||
public static Stat getByValue(int value) {
|
||||
for (Stat stat : Stat.values()) {
|
||||
if (stat.getValue() == value) {
|
||||
return stat;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Stat getBy5ByteEncoding(int encoded) {
|
||||
switch (encoded) {
|
||||
case 64:
|
||||
return STR;
|
||||
case 128:
|
||||
return DEX;
|
||||
case 256:
|
||||
return INT;
|
||||
case 512:
|
||||
return LUK;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Stat getByString(String type) {
|
||||
for (Stat stat : Stat.values()) {
|
||||
if (stat.name().equals(type)) {
|
||||
return stat;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
138
src/main/java/client/autoban/AutobanFactory.java
Normal file
138
src/main/java/client/autoban/AutobanFactory.java
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
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 client.autoban;
|
||||
|
||||
import client.Character;
|
||||
import config.YamlConfig;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.PacketCreator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
/**
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
public enum AutobanFactory {
|
||||
MOB_COUNT,
|
||||
GENERAL,
|
||||
FIX_DAMAGE,
|
||||
DAMAGE_HACK(15, MINUTES.toMillis(1)),
|
||||
DISTANCE_HACK(10, MINUTES.toMillis(2)),
|
||||
PORTAL_DISTANCE(5, SECONDS.toMillis(30)),
|
||||
PACKET_EDIT,
|
||||
ACC_HACK,
|
||||
CREATION_GENERATOR,
|
||||
HIGH_HP_HEALING,
|
||||
FAST_HP_HEALING(15),
|
||||
FAST_MP_HEALING(20, SECONDS.toMillis(30)),
|
||||
GACHA_EXP,
|
||||
TUBI(20, SECONDS.toMillis(15)),
|
||||
SHORT_ITEM_VAC,
|
||||
ITEM_VAC,
|
||||
FAST_ITEM_PICKUP(5, SECONDS.toMillis(30)),
|
||||
FAST_ATTACK(10, SECONDS.toMillis(30)),
|
||||
MPCON(25, SECONDS.toMillis(30));
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AutobanFactory.class);
|
||||
private static final Set<Integer> ignoredChrIds = new HashSet<>();
|
||||
|
||||
private final int points;
|
||||
private final long expiretime;
|
||||
|
||||
AutobanFactory() {
|
||||
this(1, -1);
|
||||
}
|
||||
|
||||
AutobanFactory(int points) {
|
||||
this.points = points;
|
||||
this.expiretime = -1;
|
||||
}
|
||||
|
||||
AutobanFactory(int points, long expire) {
|
||||
this.points = points;
|
||||
this.expiretime = expire;
|
||||
}
|
||||
|
||||
public int getMaximum() {
|
||||
return points;
|
||||
}
|
||||
|
||||
public long getExpire() {
|
||||
return expiretime;
|
||||
}
|
||||
|
||||
public void addPoint(AutobanManager ban, String reason) {
|
||||
ban.addPoint(this, reason);
|
||||
}
|
||||
|
||||
public void alert(Character chr, String reason) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
if (chr != null && isIgnored(chr.getId())) {
|
||||
return;
|
||||
}
|
||||
Server.getInstance().broadcastGMMessage((chr != null ? chr.getWorld() : 0), PacketCreator.sendYellowTip((chr != null ? Character.makeMapleReadable(chr.getName()) : "") + " caused " + this.name() + " " + reason));
|
||||
}
|
||||
if (YamlConfig.config.server.USE_AUTOBAN_LOG) {
|
||||
final String chrName = chr != null ? Character.makeMapleReadable(chr.getName()) : "";
|
||||
log.info("Autoban alert - chr {} caused {}-{}", chrName, this.name(), reason);
|
||||
}
|
||||
}
|
||||
|
||||
public void autoban(Character chr, String value) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
chr.autoban("Autobanned for (" + this.name() + ": " + value + ")");
|
||||
//chr.sendPolice("You will be disconnected for (" + this.name() + ": " + value + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle ignored status for a character id.
|
||||
* An ignored character will not trigger GM alerts.
|
||||
*
|
||||
* @return new status. true if the chrId is now ignored, otherwise false.
|
||||
*/
|
||||
public static boolean toggleIgnored(int chrId) {
|
||||
if (ignoredChrIds.contains(chrId)) {
|
||||
ignoredChrIds.remove(chrId);
|
||||
return false;
|
||||
} else {
|
||||
ignoredChrIds.add(chrId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isIgnored(int chrId) {
|
||||
return ignoredChrIds.contains(chrId);
|
||||
}
|
||||
|
||||
public static Collection<Integer> getIgnoredChrIds() {
|
||||
return ignoredChrIds;
|
||||
}
|
||||
}
|
||||
132
src/main/java/client/autoban/AutobanManager.java
Normal file
132
src/main/java/client/autoban/AutobanManager.java
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package client.autoban;
|
||||
|
||||
import client.Character;
|
||||
import config.YamlConfig;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
public class AutobanManager {
|
||||
private static final Logger log = LoggerFactory.getLogger(AutobanManager.class);
|
||||
|
||||
private final Character chr;
|
||||
private final Map<AutobanFactory, Integer> points = new HashMap<>();
|
||||
private final Map<AutobanFactory, Long> lastTime = new HashMap<>();
|
||||
private int misses = 0;
|
||||
private int lastmisses = 0;
|
||||
private int samemisscount = 0;
|
||||
private final long[] spam = new long[20];
|
||||
private final int[] timestamp = new int[20];
|
||||
private final byte[] timestampcounter = new byte[20];
|
||||
|
||||
|
||||
public AutobanManager(Character chr) {
|
||||
this.chr = chr;
|
||||
}
|
||||
|
||||
public void addPoint(AutobanFactory fac, String reason) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
if (chr.isGM() || chr.isBanned()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastTime.containsKey(fac)) {
|
||||
if (lastTime.get(fac) < (Server.getInstance().getCurrentTime() - fac.getExpire())) {
|
||||
points.put(fac, points.get(fac) / 2); //So the points are not completely gone.
|
||||
}
|
||||
}
|
||||
if (fac.getExpire() != -1) {
|
||||
lastTime.put(fac, Server.getInstance().getCurrentTime());
|
||||
}
|
||||
|
||||
if (points.containsKey(fac)) {
|
||||
points.put(fac, points.get(fac) + 1);
|
||||
} else {
|
||||
points.put(fac, 1);
|
||||
}
|
||||
|
||||
if (points.get(fac) >= fac.getMaximum()) {
|
||||
chr.autoban(reason);
|
||||
}
|
||||
}
|
||||
if (YamlConfig.config.server.USE_AUTOBAN_LOG) {
|
||||
// Lets log every single point too.
|
||||
log.info("Autoban - chr {} caused {} {}", Character.makeMapleReadable(chr.getName()), fac.name(), reason);
|
||||
}
|
||||
}
|
||||
|
||||
public void addMiss() {
|
||||
this.misses++;
|
||||
}
|
||||
|
||||
public void resetMisses() {
|
||||
if (lastmisses == misses && misses > 6) {
|
||||
samemisscount++;
|
||||
}
|
||||
if (samemisscount > 4) {
|
||||
chr.sendPolice("You will be disconnected for miss godmode.");
|
||||
}
|
||||
//chr.autoban("Autobanned for : " + misses + " Miss godmode", 1);
|
||||
else if (samemisscount > 0) {
|
||||
this.lastmisses = misses;
|
||||
}
|
||||
this.misses = 0;
|
||||
}
|
||||
|
||||
//Don't use the same type for more than 1 thing
|
||||
public void spam(int type) {
|
||||
this.spam[type] = Server.getInstance().getCurrentTime();
|
||||
}
|
||||
|
||||
public void spam(int type, int timestamp) {
|
||||
this.spam[type] = timestamp;
|
||||
}
|
||||
|
||||
public long getLastSpam(int type) {
|
||||
return spam[type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamp checker
|
||||
*
|
||||
* <code>type</code>:<br>
|
||||
* 1: Pet Food<br>
|
||||
* 2: InventoryMerge<br>
|
||||
* 3: InventorySort<br>
|
||||
* 4: SpecialMove<br>
|
||||
* 5: UseCatchItem<br>
|
||||
* 6: Item Drop<br>
|
||||
* 7: Chat<br>
|
||||
* 8: HealOverTimeHP<br>
|
||||
* 9: HealOverTimeMP<br>
|
||||
*
|
||||
* @param type type
|
||||
* @return Timestamp checker
|
||||
*/
|
||||
public void setTimestamp(int type, int time, int times) {
|
||||
if (this.timestamp[type] == time) {
|
||||
this.timestampcounter[type]++;
|
||||
if (this.timestampcounter[type] >= times) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
chr.getClient().disconnect(false, false);
|
||||
}
|
||||
|
||||
log.info("Autoban - Chr {} was caught spamming TYPE {} and has been disconnected", chr, type);
|
||||
}
|
||||
} else {
|
||||
this.timestamp[type] = time;
|
||||
this.timestampcounter[type] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
62
src/main/java/client/command/Command.java
Normal file
62
src/main/java/client/command/Command.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command;
|
||||
|
||||
import client.Client;
|
||||
|
||||
public abstract class Command {
|
||||
|
||||
protected int rank;
|
||||
protected String description;
|
||||
|
||||
public abstract void execute(Client client, String[] params);
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
protected void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
return rank;
|
||||
}
|
||||
|
||||
public void setRank(int rank) {
|
||||
this.rank = rank;
|
||||
}
|
||||
|
||||
protected String joinStringFrom(String[] arr, int start) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = start; i < arr.length; i++) {
|
||||
builder.append(arr[i]);
|
||||
if (i != arr.length - 1) {
|
||||
builder.append(" ");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
398
src/main/java/client/command/CommandsExecutor.java
Normal file
398
src/main/java/client/command/CommandsExecutor.java
Normal file
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command;
|
||||
|
||||
import client.Client;
|
||||
import client.command.commands.gm0.*;
|
||||
import client.command.commands.gm1.*;
|
||||
import client.command.commands.gm2.*;
|
||||
import client.command.commands.gm3.*;
|
||||
import client.command.commands.gm4.*;
|
||||
import client.command.commands.gm5.*;
|
||||
import client.command.commands.gm6.*;
|
||||
import constants.id.MapId;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class CommandsExecutor {
|
||||
private static final Logger log = LoggerFactory.getLogger(CommandsExecutor.class);
|
||||
private static final CommandsExecutor instance = new CommandsExecutor();
|
||||
private static final char USER_HEADING = '@';
|
||||
private static final char GM_HEADING = '!';
|
||||
|
||||
private final HashMap<String, Command> registeredCommands = new HashMap<>();
|
||||
private final List<Pair<List<String>, List<String>>> commandsNameDesc = new ArrayList<>();
|
||||
private Pair<List<String>, List<String>> levelCommandsCursor;
|
||||
|
||||
public static CommandsExecutor getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static boolean isCommand(Client client, String content) {
|
||||
char heading = content.charAt(0);
|
||||
if (client.getPlayer().isGM()) {
|
||||
return heading == USER_HEADING || heading == GM_HEADING;
|
||||
}
|
||||
return heading == USER_HEADING;
|
||||
}
|
||||
|
||||
private CommandsExecutor() {
|
||||
registerLv0Commands();
|
||||
registerLv1Commands();
|
||||
registerLv2Commands();
|
||||
registerLv3Commands();
|
||||
registerLv4Commands();
|
||||
registerLv5Commands();
|
||||
registerLv6Commands();
|
||||
}
|
||||
|
||||
public List<Pair<List<String>, List<String>>> getGmCommands() {
|
||||
return commandsNameDesc;
|
||||
}
|
||||
|
||||
public void handle(Client client, String message) {
|
||||
if (client.tryacquireClient()) {
|
||||
try {
|
||||
handleInternal(client, message);
|
||||
} finally {
|
||||
client.releaseClient();
|
||||
}
|
||||
} else {
|
||||
client.getPlayer().dropMessage(5, "Try again in a while... Latest commands are currently being processed.");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleInternal(Client client, String message) {
|
||||
if (client.getPlayer().getMapId() == MapId.JAIL) {
|
||||
client.getPlayer().yellowMessage("You do not have permission to use commands while in jail.");
|
||||
return;
|
||||
}
|
||||
final String splitRegex = "[ ]";
|
||||
String[] splitedMessage = message.substring(1).split(splitRegex, 2);
|
||||
if (splitedMessage.length < 2) {
|
||||
splitedMessage = new String[]{splitedMessage[0], ""};
|
||||
}
|
||||
|
||||
client.getPlayer().setLastCommandMessage(splitedMessage[1]); // thanks Tochi & Nulliphite for noticing string messages being marshalled lowercase
|
||||
final String commandName = splitedMessage[0].toLowerCase();
|
||||
final String[] lowercaseParams = splitedMessage[1].toLowerCase().split(splitRegex);
|
||||
|
||||
final Command command = registeredCommands.get(commandName);
|
||||
if (command == null) {
|
||||
client.getPlayer().yellowMessage("Command '" + commandName + "' is not available. See @commands for a list of available commands.");
|
||||
return;
|
||||
}
|
||||
if (client.getPlayer().gmLevel() < command.getRank()) {
|
||||
client.getPlayer().yellowMessage("You do not have permission to use this command.");
|
||||
return;
|
||||
}
|
||||
String[] params;
|
||||
if (lowercaseParams.length > 0 && !lowercaseParams[0].isEmpty()) {
|
||||
params = Arrays.copyOfRange(lowercaseParams, 0, lowercaseParams.length);
|
||||
} else {
|
||||
params = new String[]{};
|
||||
}
|
||||
|
||||
command.execute(client, params);
|
||||
log.info("Chr {} used command {}", client.getPlayer().getName(), command.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
private void addCommandInfo(String name, Class<? extends Command> commandClass) {
|
||||
try {
|
||||
levelCommandsCursor.getRight().add(commandClass.getDeclaredConstructor().newInstance().getDescription());
|
||||
levelCommandsCursor.getLeft().add(name);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void addCommand(String[] syntaxs, Class<? extends Command> commandClass) {
|
||||
for (String syntax : syntaxs) {
|
||||
addCommand(syntax, 0, commandClass);
|
||||
}
|
||||
}
|
||||
|
||||
private void addCommand(String syntax, Class<? extends Command> commandClass) {
|
||||
//for (String syntax : syntaxs){
|
||||
addCommand(syntax, 0, commandClass);
|
||||
//}
|
||||
}
|
||||
|
||||
private void addCommand(String[] surtaxes, int rank, Class<? extends Command> commandClass) {
|
||||
for (String syntax : surtaxes) {
|
||||
addCommand(syntax, rank, commandClass);
|
||||
}
|
||||
}
|
||||
|
||||
private void addCommand(String syntax, int rank, Class<? extends Command> commandClass) {
|
||||
if (registeredCommands.containsKey(syntax.toLowerCase())) {
|
||||
log.warn("Error on register command with name: {}. Already exists.", syntax);
|
||||
return;
|
||||
}
|
||||
|
||||
String commandName = syntax.toLowerCase();
|
||||
addCommandInfo(commandName, commandClass);
|
||||
|
||||
try {
|
||||
Command commandInstance = commandClass.getDeclaredConstructor().newInstance(); // thanks Halcyon for noticing commands getting reinstanced every call
|
||||
commandInstance.setRank(rank);
|
||||
|
||||
registeredCommands.put(commandName, commandInstance);
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to create command instance", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerLv0Commands() {
|
||||
levelCommandsCursor = new Pair<>(new ArrayList<String>(), new ArrayList<String>());
|
||||
|
||||
addCommand(new String[]{"help", "commands"}, HelpCommand.class);
|
||||
addCommand("droplimit", DropLimitCommand.class);
|
||||
addCommand("time", TimeCommand.class);
|
||||
addCommand("credits", StaffCommand.class);
|
||||
addCommand("buyback", BuyBackCommand.class);
|
||||
addCommand("uptime", UptimeCommand.class);
|
||||
addCommand("gacha", GachaCommand.class);
|
||||
addCommand("dispose", DisposeCommand.class);
|
||||
addCommand("changel", ChangeLanguageCommand.class);
|
||||
addCommand("equiplv", EquipLvCommand.class);
|
||||
addCommand("showrates", ShowRatesCommand.class);
|
||||
addCommand("rates", RatesCommand.class);
|
||||
addCommand("online", OnlineCommand.class);
|
||||
addCommand("gm", GmCommand.class);
|
||||
addCommand("reportbug", ReportBugCommand.class);
|
||||
addCommand("points", ReadPointsCommand.class);
|
||||
addCommand("joinevent", JoinEventCommand.class);
|
||||
addCommand("leaveevent", LeaveEventCommand.class);
|
||||
addCommand("ranks", RanksCommand.class);
|
||||
addCommand("str", StatStrCommand.class);
|
||||
addCommand("dex", StatDexCommand.class);
|
||||
addCommand("int", StatIntCommand.class);
|
||||
addCommand("luk", StatLukCommand.class);
|
||||
addCommand("enableauth", EnableAuthCommand.class);
|
||||
addCommand("toggleexp", ToggleExpCommand.class);
|
||||
addCommand("mylawn", MapOwnerClaimCommand.class);
|
||||
addCommand("bosshp", BossHpCommand.class);
|
||||
addCommand("mobhp", MobHpCommand.class);
|
||||
|
||||
commandsNameDesc.add(levelCommandsCursor);
|
||||
}
|
||||
|
||||
|
||||
private void registerLv1Commands() {
|
||||
levelCommandsCursor = new Pair<>(new ArrayList<String>(), new ArrayList<String>());
|
||||
|
||||
addCommand("whatdropsfrom", 1, WhatDropsFromCommand.class);
|
||||
addCommand("whodrops", 1, WhoDropsCommand.class);
|
||||
addCommand("buffme", 1, BuffMeCommand.class);
|
||||
addCommand("goto", 1, GotoCommand.class);
|
||||
|
||||
commandsNameDesc.add(levelCommandsCursor);
|
||||
}
|
||||
|
||||
|
||||
private void registerLv2Commands() {
|
||||
levelCommandsCursor = new Pair<>(new ArrayList<String>(), new ArrayList<String>());
|
||||
|
||||
addCommand("recharge", 2, RechargeCommand.class);
|
||||
addCommand("whereami", 2, WhereaMiCommand.class);
|
||||
addCommand("hide", 2, HideCommand.class);
|
||||
addCommand("unhide", 2, UnHideCommand.class);
|
||||
addCommand("sp", 2, SpCommand.class);
|
||||
addCommand("ap", 2, ApCommand.class);
|
||||
addCommand("empowerme", 2, EmpowerMeCommand.class);
|
||||
addCommand("buffmap", 2, BuffMapCommand.class);
|
||||
addCommand("buff", 2, BuffCommand.class);
|
||||
addCommand("bomb", 2, BombCommand.class);
|
||||
addCommand("dc", 2, DcCommand.class);
|
||||
addCommand("cleardrops", 2, ClearDropsCommand.class);
|
||||
addCommand("clearslot", 2, ClearSlotCommand.class);
|
||||
addCommand("clearsavelocs", 2, ClearSavedLocationsCommand.class);
|
||||
addCommand("warp", 2, WarpCommand.class);
|
||||
addCommand(new String[]{"warphere", "summon"}, 2, SummonCommand.class);
|
||||
addCommand(new String[]{"warpto", "reach", "follow"}, 2, ReachCommand.class);
|
||||
addCommand("gmshop", 2, GmShopCommand.class);
|
||||
addCommand("heal", 2, HealCommand.class);
|
||||
addCommand("item", 2, ItemCommand.class);
|
||||
addCommand("drop", 2, ItemDropCommand.class);
|
||||
addCommand("level", 2, LevelCommand.class);
|
||||
addCommand("levelpro", 2, LevelProCommand.class);
|
||||
addCommand("setslot", 2, SetSlotCommand.class);
|
||||
addCommand("setstat", 2, SetStatCommand.class);
|
||||
addCommand("maxstat", 2, MaxStatCommand.class);
|
||||
addCommand("maxskill", 2, MaxSkillCommand.class);
|
||||
addCommand("resetskill", 2, ResetSkillCommand.class);
|
||||
addCommand("search", 2, SearchCommand.class);
|
||||
addCommand("jail", 2, JailCommand.class);
|
||||
addCommand("unjail", 2, UnJailCommand.class);
|
||||
addCommand("job", 2, JobCommand.class);
|
||||
addCommand("unbug", 2, UnBugCommand.class);
|
||||
addCommand("id", 2, IdCommand.class);
|
||||
addCommand("gachalist", GachaListCommand.class);
|
||||
addCommand("loot", LootCommand.class);
|
||||
addCommand("mobskill", MobSkillCommand.class);
|
||||
|
||||
commandsNameDesc.add(levelCommandsCursor);
|
||||
}
|
||||
|
||||
private void registerLv3Commands() {
|
||||
levelCommandsCursor = new Pair<>(new ArrayList<String>(), new ArrayList<String>());
|
||||
|
||||
addCommand("debuff", 3, DebuffCommand.class);
|
||||
addCommand("fly", 3, FlyCommand.class);
|
||||
addCommand("spawn", 3, SpawnCommand.class);
|
||||
addCommand("mutemap", 3, MuteMapCommand.class);
|
||||
addCommand("checkdmg", 3, CheckDmgCommand.class);
|
||||
addCommand("inmap", 3, InMapCommand.class);
|
||||
addCommand("reloadevents", 3, ReloadEventsCommand.class);
|
||||
addCommand("reloaddrops", 3, ReloadDropsCommand.class);
|
||||
addCommand("reloadportals", 3, ReloadPortalsCommand.class);
|
||||
addCommand("reloadmap", 3, ReloadMapCommand.class);
|
||||
addCommand("reloadshops", 3, ReloadShopsCommand.class);
|
||||
addCommand("hpmp", 3, HpMpCommand.class);
|
||||
addCommand("maxhpmp", 3, MaxHpMpCommand.class);
|
||||
addCommand("music", 3, MusicCommand.class);
|
||||
addCommand("monitor", 3, MonitorCommand.class);
|
||||
addCommand("monitors", 3, MonitorsCommand.class);
|
||||
addCommand("ignore", 3, IgnoreCommand.class);
|
||||
addCommand("ignored", 3, IgnoredCommand.class);
|
||||
addCommand("pos", 3, PosCommand.class);
|
||||
addCommand("togglecoupon", 3, ToggleCouponCommand.class);
|
||||
addCommand("togglewhitechat", 3, ChatCommand.class);
|
||||
addCommand("fame", 3, FameCommand.class);
|
||||
addCommand("givenx", 3, GiveNxCommand.class);
|
||||
addCommand("givevp", 3, GiveVpCommand.class);
|
||||
addCommand("givems", 3, GiveMesosCommand.class);
|
||||
addCommand("giverp", 3, GiveRpCommand.class);
|
||||
addCommand("expeds", 3, ExpedsCommand.class);
|
||||
addCommand("kill", 3, KillCommand.class);
|
||||
addCommand("seed", 3, SeedCommand.class);
|
||||
addCommand("maxenergy", 3, MaxEnergyCommand.class);
|
||||
addCommand("killall", 3, KillAllCommand.class);
|
||||
addCommand("notice", 3, NoticeCommand.class);
|
||||
addCommand("rip", 3, RipCommand.class);
|
||||
addCommand("openportal", 3, OpenPortalCommand.class);
|
||||
addCommand("closeportal", 3, ClosePortalCommand.class);
|
||||
addCommand("pe", 3, PeCommand.class);
|
||||
addCommand("startevent", 3, StartEventCommand.class);
|
||||
addCommand("endevent", 3, EndEventCommand.class);
|
||||
addCommand("startmapevent", 3, StartMapEventCommand.class);
|
||||
addCommand("stopmapevent", 3, StopMapEventCommand.class);
|
||||
addCommand("online2", 3, OnlineTwoCommand.class);
|
||||
addCommand("ban", 3, BanCommand.class);
|
||||
addCommand("unban", 3, UnBanCommand.class);
|
||||
addCommand("healmap", 3, HealMapCommand.class);
|
||||
addCommand("healperson", 3, HealPersonCommand.class);
|
||||
addCommand("hurt", 3, HurtCommand.class);
|
||||
addCommand("killmap", 3, KillMapCommand.class);
|
||||
addCommand("night", 3, NightCommand.class);
|
||||
addCommand("npc", 3, NpcCommand.class);
|
||||
addCommand("face", 3, FaceCommand.class);
|
||||
addCommand("hair", 3, HairCommand.class);
|
||||
addCommand("startquest", 3, QuestStartCommand.class);
|
||||
addCommand("completequest", 3, QuestCompleteCommand.class);
|
||||
addCommand("resetquest", 3, QuestResetCommand.class);
|
||||
addCommand("timer", 3, TimerCommand.class);
|
||||
addCommand("timermap", 3, TimerMapCommand.class);
|
||||
addCommand("timerall", 3, TimerAllCommand.class);
|
||||
addCommand("warpmap", 3, WarpMapCommand.class);
|
||||
addCommand("warparea", 3, WarpAreaCommand.class);
|
||||
|
||||
commandsNameDesc.add(levelCommandsCursor);
|
||||
}
|
||||
|
||||
private void registerLv4Commands() {
|
||||
levelCommandsCursor = new Pair<>(new ArrayList<String>(), new ArrayList<String>());
|
||||
|
||||
addCommand("servermessage", 4, ServerMessageCommand.class);
|
||||
addCommand("proitem", 4, ProItemCommand.class);
|
||||
addCommand("seteqstat", 4, SetEqStatCommand.class);
|
||||
addCommand("exprate", 4, ExpRateCommand.class);
|
||||
addCommand("mesorate", 4, MesoRateCommand.class);
|
||||
addCommand("droprate", 4, DropRateCommand.class);
|
||||
addCommand("bossdroprate", 4, BossDropRateCommand.class);
|
||||
addCommand("questrate", 4, QuestRateCommand.class);
|
||||
addCommand("travelrate", 4, TravelRateCommand.class);
|
||||
addCommand("fishrate", 4, FishingRateCommand.class);
|
||||
addCommand("itemvac", 4, ItemVacCommand.class);
|
||||
addCommand("forcevac", 4, ForceVacCommand.class);
|
||||
addCommand("zakum", 4, ZakumCommand.class);
|
||||
addCommand("horntail", 4, HorntailCommand.class);
|
||||
addCommand("pinkbean", 4, PinkbeanCommand.class);
|
||||
addCommand("pap", 4, PapCommand.class);
|
||||
addCommand("pianus", 4, PianusCommand.class);
|
||||
addCommand("cake", 4, CakeCommand.class);
|
||||
addCommand("playernpc", 4, PlayerNpcCommand.class);
|
||||
addCommand("playernpcremove", 4, PlayerNpcRemoveCommand.class);
|
||||
addCommand("pnpc", 4, PnpcCommand.class);
|
||||
addCommand("pnpcremove", 4, PnpcRemoveCommand.class);
|
||||
addCommand("pmob", 4, PmobCommand.class);
|
||||
addCommand("pmobremove", 4, PmobRemoveCommand.class);
|
||||
|
||||
commandsNameDesc.add(levelCommandsCursor);
|
||||
}
|
||||
|
||||
private void registerLv5Commands() {
|
||||
levelCommandsCursor = new Pair<>(new ArrayList<String>(), new ArrayList<String>());
|
||||
|
||||
addCommand("debug", 5, DebugCommand.class);
|
||||
addCommand("set", 5, SetCommand.class);
|
||||
addCommand("showpackets", 5, ShowPacketsCommand.class);
|
||||
addCommand("showmovelife", 5, ShowMoveLifeCommand.class);
|
||||
addCommand("showsessions", 5, ShowSessionsCommand.class);
|
||||
addCommand("iplist", 5, IpListCommand.class);
|
||||
|
||||
commandsNameDesc.add(levelCommandsCursor);
|
||||
}
|
||||
|
||||
private void registerLv6Commands() {
|
||||
levelCommandsCursor = new Pair<>(new ArrayList<String>(), new ArrayList<String>());
|
||||
|
||||
addCommand("setgmlevel", 6, SetGmLevelCommand.class);
|
||||
addCommand("warpworld", 6, WarpWorldCommand.class);
|
||||
addCommand("saveall", 6, SaveAllCommand.class);
|
||||
addCommand("dcall", 6, DCAllCommand.class);
|
||||
addCommand("mapplayers", 6, MapPlayersCommand.class);
|
||||
addCommand("getacc", 6, GetAccCommand.class);
|
||||
addCommand("shutdown", 6, ShutdownCommand.class);
|
||||
addCommand("clearquestcache", 6, ClearQuestCacheCommand.class);
|
||||
addCommand("clearquest", 6, ClearQuestCommand.class);
|
||||
addCommand("supplyratecoupon", 6, SupplyRateCouponCommand.class);
|
||||
addCommand("spawnallpnpcs", 6, SpawnAllPNpcsCommand.class);
|
||||
addCommand("eraseallpnpcs", 6, EraseAllPNpcsCommand.class);
|
||||
addCommand("addchannel", 6, ServerAddChannelCommand.class);
|
||||
addCommand("addworld", 6, ServerAddWorldCommand.class);
|
||||
addCommand("removechannel", 6, ServerRemoveChannelCommand.class);
|
||||
addCommand("removeworld", 6, ServerRemoveWorldCommand.class);
|
||||
|
||||
commandsNameDesc.add(levelCommandsCursor);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.processor.action.BuybackProcessor;
|
||||
|
||||
public class BuyBackCommand extends Command {
|
||||
{
|
||||
setDescription("Revive yourself after a death.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
if (params.length < 1) {
|
||||
c.getPlayer().yellowMessage("Syntax: @buyback <info|now>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params[0].contentEquals("now")) {
|
||||
BuybackProcessor.processBuyback(c);
|
||||
} else {
|
||||
c.getPlayer().showBuybackInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class ChangeLanguageCommand extends Command {
|
||||
{
|
||||
setDescription("Change language settings.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
if (params.length < 1) {
|
||||
c.getPlayer().yellowMessage("Syntax: !changel <0=ptb, 1=esp, 2=eng>");
|
||||
return;
|
||||
}
|
||||
c.setLanguage(Integer.parseInt(params[0]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import scripting.npc.NPCScriptManager;
|
||||
import scripting.quest.QuestScriptManager;
|
||||
import tools.PacketCreator;
|
||||
|
||||
public class DisposeCommand extends Command {
|
||||
{
|
||||
setDescription("Dispose to fix NPC chat.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
NPCScriptManager.getInstance().dispose(c);
|
||||
QuestScriptManager.getInstance().dispose(c);
|
||||
c.sendPacket(PacketCreator.enableActions());
|
||||
c.removeClickedNPC();
|
||||
c.getPlayer().message("You've been disposed.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class DropLimitCommand extends Command {
|
||||
{
|
||||
setDescription("Check drop limit of current map.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
int dropCount = c.getPlayer().getMap().getDroppedItemCount();
|
||||
if (((float) dropCount) / YamlConfig.config.server.ITEM_LIMIT_ON_MAP < 0.75f) {
|
||||
c.getPlayer().showHint("Current drop count: #b" + dropCount + "#k / #e" + YamlConfig.config.server.ITEM_LIMIT_ON_MAP + "#n", 300);
|
||||
} else {
|
||||
c.getPlayer().showHint("Current drop count: #r" + dropCount + "#k / #e" + YamlConfig.config.server.ITEM_LIMIT_ON_MAP + "#n", 300);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import net.server.coordinator.login.LoginBypassCoordinator;
|
||||
|
||||
public class EnableAuthCommand extends Command {
|
||||
{
|
||||
setDescription("Enable PIC code by resetting the cooldown.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
if (c.tryacquireClient()) {
|
||||
try {
|
||||
LoginBypassCoordinator.getInstance().unregisterLoginBypassEntry(c.getHwid(), c.getAccID());
|
||||
} finally {
|
||||
c.releaseClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class EquipLvCommand extends Command {
|
||||
{
|
||||
setDescription("Show levels of all equipped items.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
c.getPlayer().showAllEquipFeatures();
|
||||
}
|
||||
}
|
||||
69
src/main/java/client/command/commands/gm0/GachaCommand.java
Normal file
69
src/main/java/client/command/commands/gm0/GachaCommand.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.id.NpcId;
|
||||
import server.ItemInformationProvider;
|
||||
import server.gachapon.Gachapon;
|
||||
|
||||
public class GachaCommand extends Command {
|
||||
{
|
||||
setDescription("Show gachapon rewards.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Gachapon.GachaponType gacha = null;
|
||||
String search = c.getPlayer().getLastCommandMessage();
|
||||
String gachaName = "";
|
||||
String[] names = {"Henesys", "Ellinia", "Perion", "Kerning City", "Sleepywood", "Mushroom Shrine", "Showa Spa Male", "Showa Spa Female", "New Leaf City", "Nautilus Harbor"};
|
||||
int[] ids = {NpcId.GACHAPON_HENESYS, NpcId.GACHAPON_ELLINIA, NpcId.GACHAPON_PERION, NpcId.GACHAPON_KERNING,
|
||||
NpcId.GACHAPON_SLEEPYWOOD, NpcId.GACHAPON_MUSHROOM_SHRINE, NpcId.GACHAPON_SHOWA_MALE,
|
||||
NpcId.GACHAPON_SHOWA_FEMALE, NpcId.GACHAPON_NLC, NpcId.GACHAPON_NAUTILUS};
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
if (search.equalsIgnoreCase(names[i])) {
|
||||
gachaName = names[i];
|
||||
gacha = Gachapon.GachaponType.getByNpcId(ids[i]);
|
||||
}
|
||||
}
|
||||
if (gacha == null) {
|
||||
c.getPlayer().yellowMessage("Please use @gacha <name> where name corresponds to one of the below:");
|
||||
for (String name : names) {
|
||||
c.getPlayer().yellowMessage(name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
String talkStr = "The #b" + gachaName + "#k Gachapon contains the following items.\r\n\r\n";
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int id : gacha.getItems(i)) {
|
||||
talkStr += "-" + ItemInformationProvider.getInstance().getName(id) + "\r\n";
|
||||
}
|
||||
}
|
||||
talkStr += "\r\nPlease keep in mind that there are items that are in all gachapons and are not listed here.";
|
||||
|
||||
c.getAbstractPlayerInteraction().npcTalk(NpcId.MAPLE_ADMINISTRATOR, talkStr);
|
||||
}
|
||||
}
|
||||
63
src/main/java/client/command/commands/gm0/GmCommand.java
Normal file
63
src/main/java/client/command/commands/gm0/GmCommand.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.PacketCreator;
|
||||
import tools.Randomizer;
|
||||
|
||||
public class GmCommand extends Command {
|
||||
{
|
||||
setDescription("Send a message to the game masters.");
|
||||
}
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(GmCommand.class);
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
String[] tips = {
|
||||
"Please only use @gm in emergencies or to report somebody.",
|
||||
"To report a bug or make a suggestion, use the forum.",
|
||||
"Please do not use @gm to ask if a GM is online.",
|
||||
"Do not ask if you can receive help, just state your issue.",
|
||||
"Do not say 'I have a bug to report', just state it.",
|
||||
};
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1 || params[0].length() < 3) { // #goodbye 'hi'
|
||||
player.dropMessage(5, "Your message was too short. Please provide as much detail as possible.");
|
||||
return;
|
||||
}
|
||||
String message = player.getLastCommandMessage();
|
||||
Server.getInstance().broadcastGMMessage(c.getWorld(), PacketCreator.sendYellowTip("[GM Message]:" + Character.makeMapleReadable(player.getName()) + ": " + message));
|
||||
Server.getInstance().broadcastGMMessage(c.getWorld(), PacketCreator.serverNotice(1, message));
|
||||
log.info("{}: {}", Character.makeMapleReadable(player.getName()), message);
|
||||
player.dropMessage(5, "Your message '" + message + "' was sent to GMs.");
|
||||
player.dropMessage(5, tips[Randomizer.nextInt(tips.length)]);
|
||||
}
|
||||
}
|
||||
39
src/main/java/client/command/commands/gm0/HelpCommand.java
Normal file
39
src/main/java/client/command/commands/gm0/HelpCommand.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.id.NpcId;
|
||||
|
||||
public class HelpCommand extends Command {
|
||||
{
|
||||
setDescription("Show available commands.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
client.getAbstractPlayerInteraction().openNpc(NpcId.STEWARD, "commands");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.id.MapId;
|
||||
import server.events.gm.Event;
|
||||
import server.maps.FieldLimit;
|
||||
|
||||
public class JoinEventCommand extends Command {
|
||||
{
|
||||
setDescription("Join active event.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (!FieldLimit.CANNOTMIGRATE.check(player.getMap().getFieldLimit())) {
|
||||
Event event = c.getChannelServer().getEvent();
|
||||
if (event != null) {
|
||||
if (event.getMapId() != player.getMapId()) {
|
||||
if (event.getLimit() > 0) {
|
||||
player.saveLocation("EVENT");
|
||||
|
||||
if (event.getMapId() == MapId.EVENT_COCONUT_HARVEST || event.getMapId() == MapId.EVENT_SNOWBALL_ENTRANCE) {
|
||||
player.setTeam(event.getLimit() % 2);
|
||||
}
|
||||
|
||||
event.minusLimit();
|
||||
|
||||
player.saveLocationOnWarp();
|
||||
player.changeMap(event.getMapId());
|
||||
} else {
|
||||
player.dropMessage(5, "The limit of players for the event has already been reached.");
|
||||
}
|
||||
} else {
|
||||
player.dropMessage(5, "You are already in the event.");
|
||||
}
|
||||
} else {
|
||||
player.dropMessage(5, "There is currently no event in progress.");
|
||||
}
|
||||
} else {
|
||||
player.dropMessage(5, "You are currently in a map where you can't join an event.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class LeaveEventCommand extends Command {
|
||||
{
|
||||
setDescription("Leave active event.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
int returnMap = player.getSavedLocation("EVENT");
|
||||
if (returnMap != -1) {
|
||||
if (player.getOla() != null) {
|
||||
player.getOla().resetTimes();
|
||||
player.setOla(null);
|
||||
}
|
||||
if (player.getFitness() != null) {
|
||||
player.getFitness().resetTimes();
|
||||
player.setFitness(null);
|
||||
}
|
||||
|
||||
player.saveLocationOnWarp();
|
||||
player.changeMap(returnMap);
|
||||
if (c.getChannelServer().getEvent() != null) {
|
||||
c.getChannelServer().getEvent().addLimit();
|
||||
}
|
||||
} else {
|
||||
player.dropMessage(5, "You are not currently in an event.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Ronan
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
import server.maps.MapleMap;
|
||||
|
||||
public class MapOwnerClaimCommand extends Command {
|
||||
{
|
||||
setDescription("Claim ownership of the current map.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
if (c.tryacquireClient()) {
|
||||
try {
|
||||
Character chr = c.getPlayer();
|
||||
|
||||
if (YamlConfig.config.server.USE_MAP_OWNERSHIP_SYSTEM) {
|
||||
if (chr.getEventInstance() == null) {
|
||||
MapleMap map = chr.getMap();
|
||||
if (map.countBosses() == 0) { // thanks Conrad for suggesting bosses prevent map leasing
|
||||
MapleMap ownedMap = chr.getOwnedMap(); // thanks Conrad for suggesting not unlease a map as soon as player exits it
|
||||
if (ownedMap != null) {
|
||||
ownedMap.unclaimOwnership(chr);
|
||||
|
||||
if (map == ownedMap) {
|
||||
chr.dropMessage(5, "This lawn is now free real estate.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (map.claimOwnership(chr)) {
|
||||
chr.dropMessage(5, "You have leased this lawn for a while, until you leave here or after 1 minute of inactivity.");
|
||||
} else {
|
||||
chr.dropMessage(5, "This lawn has already been leased by a player.");
|
||||
}
|
||||
} else {
|
||||
chr.dropMessage(5, "This lawn is currently under a boss siege.");
|
||||
}
|
||||
} else {
|
||||
chr.dropMessage(5, "This lawn cannot be leased.");
|
||||
}
|
||||
} else {
|
||||
chr.dropMessage(5, "Feature unavailable.");
|
||||
}
|
||||
} finally {
|
||||
c.releaseClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/main/java/client/command/commands/gm0/OnlineCommand.java
Normal file
49
src/main/java/client/command/commands/gm0/OnlineCommand.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import net.server.Server;
|
||||
import net.server.channel.Channel;
|
||||
|
||||
public class OnlineCommand extends Command {
|
||||
{
|
||||
setDescription("Show all online players.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
for (Channel ch : Server.getInstance().getChannelsFromWorld(player.getWorld())) {
|
||||
player.yellowMessage("Players in Channel " + ch.getId() + ":");
|
||||
for (Character chr : ch.getPlayerStorage().getAllCharacters()) {
|
||||
if (!chr.isGM()) {
|
||||
player.message(" >> " + Character.makeMapleReadable(chr.getName()) + " is at " + chr.getMap().getMapName() + ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
src/main/java/client/command/commands/gm0/RanksCommand.java
Normal file
48
src/main/java/client/command/commands/gm0/RanksCommand.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.id.NpcId;
|
||||
import net.server.Server;
|
||||
import net.server.guild.GuildPackets;
|
||||
import tools.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RanksCommand extends Command {
|
||||
{
|
||||
setDescription("Show player rankings.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
List<Pair<String, Integer>> worldRanking = Server.getInstance().getWorldPlayerRanking(player.getWorld());
|
||||
player.sendPacket(GuildPackets.showPlayerRanks(NpcId.MAPLE_ADMINISTRATOR, worldRanking));
|
||||
}
|
||||
}
|
||||
52
src/main/java/client/command/commands/gm0/RatesCommand.java
Normal file
52
src/main/java/client/command/commands/gm0/RatesCommand.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class RatesCommand extends Command {
|
||||
{
|
||||
setDescription("Show your rates.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
// travel rates not applicable since it's intrinsically a server/environment rate rather than a character rate
|
||||
String showMsg_ = "#eCHARACTER RATES#n" + "\r\n\r\n";
|
||||
showMsg_ += "EXP Rate: #e#b" + player.getExpRate() + "x#k#n" + (player.hasNoviceExpRate() ? " - novice rate" : "") + "\r\n";
|
||||
showMsg_ += "MESO Rate: #e#b" + player.getMesoRate() + "x#k#n" + "\r\n";
|
||||
showMsg_ += "DROP Rate: #e#b" + player.getDropRate() + "x#k#n" + "\r\n";
|
||||
showMsg_ += "BOSS DROP Rate: #e#b" + player.getBossDropRate() + "x#k#n" + "\r\n";
|
||||
if (YamlConfig.config.server.USE_QUEST_RATE) {
|
||||
showMsg_ += "QUEST Rate: #e#b" + c.getWorldServer().getQuestRate() + "x#k#n" + "\r\n";
|
||||
}
|
||||
|
||||
player.showHint(showMsg_, 300);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class ReadPointsCommand extends Command {
|
||||
{
|
||||
setDescription("Show point total.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
|
||||
Character player = client.getPlayer();
|
||||
if (params.length > 2) {
|
||||
player.yellowMessage("Syntax: @points (rp|vp|all)");
|
||||
return;
|
||||
} else if (params.length == 0) {
|
||||
player.yellowMessage("RewardPoints: " + player.getRewardPoints() + " | "
|
||||
+ "VotePoints: " + player.getClient().getVotePoints());
|
||||
return;
|
||||
}
|
||||
|
||||
switch (params[0]) {
|
||||
case "rp":
|
||||
player.yellowMessage("RewardPoints: " + player.getRewardPoints());
|
||||
break;
|
||||
case "vp":
|
||||
player.yellowMessage("VotePoints: " + player.getClient().getVotePoints());
|
||||
break;
|
||||
default:
|
||||
player.yellowMessage("RewardPoints: " + player.getRewardPoints() + " | "
|
||||
+ "VotePoints: " + player.getClient().getVotePoints());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.PacketCreator;
|
||||
|
||||
public class ReportBugCommand extends Command {
|
||||
{
|
||||
setDescription("Send in a bug report.");
|
||||
}
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ReportBugCommand.class);
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
if (params.length < 1) {
|
||||
player.dropMessage(5, "Message too short and not sent. Please do @bug <bug>");
|
||||
return;
|
||||
}
|
||||
String message = player.getLastCommandMessage();
|
||||
Server.getInstance().broadcastGMMessage(c.getWorld(), PacketCreator.sendYellowTip("[Bug]:" + Character.makeMapleReadable(player.getName()) + ": " + message));
|
||||
Server.getInstance().broadcastGMMessage(c.getWorld(), PacketCreator.serverNotice(1, message));
|
||||
log.info("{}: {}", Character.makeMapleReadable(player.getName()), message);
|
||||
player.dropMessage(5, "Your bug '" + message + "' was submitted successfully to our developers. Thank you!");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class ShowRatesCommand extends Command {
|
||||
{
|
||||
setDescription("Show all world/character rates.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
String showMsg = "#eEXP RATE#n" + "\r\n";
|
||||
showMsg += "World EXP Rate: #k" + c.getWorldServer().getExpRate() + "x#k" + "\r\n";
|
||||
showMsg += "Player EXP Rate: #k" + player.getRawExpRate() + "x#k" + "\r\n";
|
||||
if (player.getCouponExpRate() != 1) {
|
||||
showMsg += "Coupon EXP Rate: #k" + player.getCouponExpRate() + "x#k" + "\r\n";
|
||||
}
|
||||
showMsg += "EXP Rate: #e#b" + player.getExpRate() + "x#k#n" + (player.hasNoviceExpRate() ? " - novice rate" : "") + "\r\n";
|
||||
|
||||
showMsg += "\r\n" + "#eMESO RATE#n" + "\r\n";
|
||||
showMsg += "World MESO Rate: #k" + c.getWorldServer().getMesoRate() + "x#k" + "\r\n";
|
||||
showMsg += "Player MESO Rate: #k" + player.getRawMesoRate() + "x#k" + "\r\n";
|
||||
if (player.getCouponMesoRate() != 1) {
|
||||
showMsg += "Coupon MESO Rate: #k" + player.getCouponMesoRate() + "x#k" + "\r\n";
|
||||
}
|
||||
showMsg += "MESO Rate: #e#b" + player.getMesoRate() + "x#k#n" + "\r\n";
|
||||
|
||||
showMsg += "\r\n" + "#eDROP RATE#n" + "\r\n";
|
||||
showMsg += "World DROP Rate: #k" + c.getWorldServer().getDropRate() + "x#k" + "\r\n";
|
||||
showMsg += "Player DROP Rate: #k" + player.getRawDropRate() + "x#k" + "\r\n";
|
||||
if (player.getCouponDropRate() != 1) {
|
||||
showMsg += "Coupon DROP Rate: #k" + player.getCouponDropRate() + "x#k" + "\r\n";
|
||||
}
|
||||
showMsg += "DROP Rate: #e#b" + player.getDropRate() + "x#k#n" + "\r\n";
|
||||
|
||||
showMsg += "\r\n" + "#eBOSS DROP RATE#n" + "\r\n";
|
||||
showMsg += "World BOSS DROP Rate: #k" + c.getWorldServer().getBossDropRate() + "x#k" + "\r\n";
|
||||
showMsg += "Player DROP Rate: #k" + player.getRawDropRate() + "x#k" + "\r\n";
|
||||
if (player.getCouponDropRate() != 1) {
|
||||
showMsg += "Coupon DROP Rate: #k" + player.getCouponDropRate() + "x#k" + "\r\n";
|
||||
}
|
||||
showMsg += "BOSS DROP Rate: #e#b" + player.getBossDropRate() + "x#k#n" + "\r\n";
|
||||
|
||||
if (YamlConfig.config.server.USE_QUEST_RATE) {
|
||||
showMsg += "\r\n" + "#eQUEST RATE#n" + "\r\n";
|
||||
showMsg += "World QUEST Rate: #e#b" + c.getWorldServer().getQuestRate() + "x#k#n" + "\r\n";
|
||||
}
|
||||
|
||||
showMsg += "\r\n";
|
||||
showMsg += "World TRAVEL Rate: #e#b" + c.getWorldServer().getTravelRate() + "x#k#n" + "\r\n";
|
||||
|
||||
player.showHint(showMsg, 300);
|
||||
}
|
||||
}
|
||||
39
src/main/java/client/command/commands/gm0/StaffCommand.java
Normal file
39
src/main/java/client/command/commands/gm0/StaffCommand.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.id.NpcId;
|
||||
|
||||
public class StaffCommand extends Command {
|
||||
{
|
||||
setDescription("Show credits. These people made the server possible.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
c.getAbstractPlayerInteraction().openNpc(NpcId.HERACLE, "credits");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatDexCommand extends Command {
|
||||
{
|
||||
setDescription("Assign AP into DEX.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
|
||||
int amount;
|
||||
if (params.length > 0) {
|
||||
try {
|
||||
amount = Math.min(Integer.parseInt(params[0]), remainingAp);
|
||||
} catch (NumberFormatException e) {
|
||||
player.dropMessage("That is not a valid number!");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
amount = Math.min(remainingAp, YamlConfig.config.server.MAX_AP - player.getDex());
|
||||
}
|
||||
if (!player.assignDex(Math.max(amount, 0))) {
|
||||
player.dropMessage("Please make sure your AP is not over " + YamlConfig.config.server.MAX_AP + " and you have enough to distribute.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatIntCommand extends Command {
|
||||
{
|
||||
setDescription("Assign AP into INT.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
|
||||
int amount;
|
||||
if (params.length > 0) {
|
||||
try {
|
||||
amount = Math.min(Integer.parseInt(params[0]), remainingAp);
|
||||
} catch (NumberFormatException e) {
|
||||
player.dropMessage("That is not a valid number!");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
amount = Math.min(remainingAp, YamlConfig.config.server.MAX_AP - player.getInt());
|
||||
}
|
||||
if (!player.assignInt(Math.max(amount, 0))) {
|
||||
player.dropMessage("Please make sure your AP is not over " + YamlConfig.config.server.MAX_AP + " and you have enough to distribute.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatLukCommand extends Command {
|
||||
{
|
||||
setDescription("Assign AP into LUK.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
|
||||
int amount;
|
||||
if (params.length > 0) {
|
||||
try {
|
||||
amount = Math.min(Integer.parseInt(params[0]), remainingAp);
|
||||
} catch (NumberFormatException e) {
|
||||
player.dropMessage("That is not a valid number!");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
amount = Math.min(remainingAp, YamlConfig.config.server.MAX_AP - player.getLuk());
|
||||
}
|
||||
if (!player.assignLuk(Math.max(amount, 0))) {
|
||||
player.dropMessage("Please make sure your AP is not over " + YamlConfig.config.server.MAX_AP + " and you have enough to distribute.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatStrCommand extends Command {
|
||||
{
|
||||
setDescription("Assign AP into STR.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
int amount;
|
||||
if (params.length > 0) {
|
||||
try {
|
||||
amount = Math.min(Integer.parseInt(params[0]), remainingAp);
|
||||
} catch (NumberFormatException e) {
|
||||
player.dropMessage("That is not a valid number!");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
amount = Math.min(remainingAp, YamlConfig.config.server.MAX_AP - player.getStr());
|
||||
}
|
||||
|
||||
if (!player.assignStr(Math.max(amount, 0))) {
|
||||
player.dropMessage("Please make sure your AP is not over " + YamlConfig.config.server.MAX_AP + " and you have enough to distribute.");
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/main/java/client/command/commands/gm0/TimeCommand.java
Normal file
45
src/main/java/client/command/commands/gm0/TimeCommand.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class TimeCommand extends Command {
|
||||
{
|
||||
setDescription("Show current server time.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
|
||||
dateFormat.setTimeZone(TimeZone.getDefault());
|
||||
client.getPlayer().yellowMessage("Cosmic Server Time: " + dateFormat.format(new Date()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Ronan
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class ToggleExpCommand extends Command {
|
||||
{
|
||||
setDescription("Toggle enable/disable all exp gain.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
if (c.tryacquireClient()) {
|
||||
try {
|
||||
c.getPlayer().toggleExpGain(); // Vcoc's idea
|
||||
} finally {
|
||||
c.releaseClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
src/main/java/client/command/commands/gm0/UptimeCommand.java
Normal file
46
src/main/java/client/command/commands/gm0/UptimeCommand.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import net.server.Server;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.*;
|
||||
|
||||
public class UptimeCommand extends Command {
|
||||
{
|
||||
setDescription("Show server online time.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
long milliseconds = System.currentTimeMillis() - Server.uptime;
|
||||
int seconds = (int) (milliseconds / SECONDS.toMillis(1)) % 60;
|
||||
int minutes = (int) ((milliseconds / MINUTES.toMillis(1)) % 60);
|
||||
int hours = (int) ((milliseconds / HOURS.toMillis(1)) % 24);
|
||||
int days = (int) ((milliseconds / DAYS.toMillis(1)));
|
||||
c.getPlayer().yellowMessage("Server has been online for " + days + " days " + hours + " hours " + minutes + " minutes and " + seconds + " seconds.");
|
||||
}
|
||||
}
|
||||
52
src/main/java/client/command/commands/gm1/BossHpCommand.java
Normal file
52
src/main/java/client/command/commands/gm1/BossHpCommand.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm1;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.life.Monster;
|
||||
|
||||
public class BossHpCommand extends Command {
|
||||
{
|
||||
setDescription("Show HP of bosses on current map.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
for (Monster monster : player.getMap().getAllMonsters()) {
|
||||
if (monster != null && monster.isBoss() && monster.getHp() > 0) {
|
||||
long percent = monster.getHp() * 100L / monster.getMaxHp();
|
||||
String bar = "[";
|
||||
for (int i = 0; i < 100; i++) {
|
||||
bar += i < percent ? "|" : ".";
|
||||
}
|
||||
bar += "]";
|
||||
player.yellowMessage(monster.getName() + " (" + monster.getId() + ") has " + percent + "% HP left.");
|
||||
player.yellowMessage("HP: " + bar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
src/main/java/client/command/commands/gm1/BuffMeCommand.java
Normal file
46
src/main/java/client/command/commands/gm1/BuffMeCommand.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm1;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
|
||||
public class BuffMeCommand extends Command {
|
||||
{
|
||||
setDescription("Activate GM buffs on self.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
SkillFactory.getSkill(4101004).getEffect(SkillFactory.getSkill(4101004).getMaxLevel()).applyTo(player);
|
||||
SkillFactory.getSkill(2311003).getEffect(SkillFactory.getSkill(2311003).getMaxLevel()).applyTo(player);
|
||||
SkillFactory.getSkill(1301007).getEffect(SkillFactory.getSkill(1301007).getMaxLevel()).applyTo(player);
|
||||
SkillFactory.getSkill(2301004).getEffect(SkillFactory.getSkill(2301004).getMaxLevel()).applyTo(player);
|
||||
SkillFactory.getSkill(1005).getEffect(SkillFactory.getSkill(1005).getMaxLevel()).applyTo(player);
|
||||
player.healHpMp();
|
||||
}
|
||||
}
|
||||
125
src/main/java/client/command/commands/gm1/GotoCommand.java
Normal file
125
src/main/java/client/command/commands/gm1/GotoCommand.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm1;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.game.GameConstants;
|
||||
import constants.id.NpcId;
|
||||
import server.maps.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class GotoCommand extends Command {
|
||||
|
||||
{
|
||||
setDescription("Warp to a predefined map.");
|
||||
|
||||
List<Entry<String, Integer>> towns = new ArrayList<>(GameConstants.GOTO_TOWNS.entrySet());
|
||||
sortGotoEntries(towns);
|
||||
|
||||
try {
|
||||
// thanks shavit for noticing goto areas getting loaded from wz needlessly only for the name retrieval
|
||||
|
||||
for (Map.Entry<String, Integer> e : towns) {
|
||||
GOTO_TOWNS_INFO += ("'" + e.getKey() + "' - #b" + (MapFactory.loadPlaceName(e.getValue())) + "#k\r\n");
|
||||
}
|
||||
|
||||
List<Entry<String, Integer>> areas = new ArrayList<>(GameConstants.GOTO_AREAS.entrySet());
|
||||
sortGotoEntries(areas);
|
||||
for (Map.Entry<String, Integer> e : areas) {
|
||||
GOTO_AREAS_INFO += ("'" + e.getKey() + "' - #b" + (MapFactory.loadPlaceName(e.getValue())) + "#k\r\n");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
GOTO_TOWNS_INFO = "(none)";
|
||||
GOTO_AREAS_INFO = "(none)";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String GOTO_TOWNS_INFO = "";
|
||||
public static String GOTO_AREAS_INFO = "";
|
||||
|
||||
private static void sortGotoEntries(List<Entry<String, Integer>> listEntries) {
|
||||
listEntries.sort((e1, e2) -> e1.getValue().compareTo(e2.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
String sendStr = "Syntax: #b@goto <map name>#k. Available areas:\r\n\r\n#rTowns:#k\r\n" + GOTO_TOWNS_INFO;
|
||||
if (player.isGM()) {
|
||||
sendStr += ("\r\n#rAreas:#k\r\n" + GOTO_AREAS_INFO);
|
||||
}
|
||||
|
||||
player.getAbstractPlayerInteraction().npcTalk(NpcId.SPINEL, sendStr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.isAlive()) {
|
||||
player.dropMessage(1, "This command cannot be used when you're dead.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.isGM()) {
|
||||
if (player.getEventInstance() != null || MiniDungeonInfo.isDungeonMap(player.getMapId()) || FieldLimit.CANNOTMIGRATE.check(player.getMap().getFieldLimit())) {
|
||||
player.dropMessage(1, "This command can not be used in this map.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Integer> gotomaps;
|
||||
if (player.isGM()) {
|
||||
gotomaps = new HashMap<>(GameConstants.GOTO_AREAS); // distinct map registry for GM/users suggested thanks to Vcoc
|
||||
gotomaps.putAll(GameConstants.GOTO_TOWNS); // thanks Halcyon (UltimateMors) for pointing out duplicates on listed entries functionality
|
||||
} else {
|
||||
gotomaps = GameConstants.GOTO_TOWNS;
|
||||
}
|
||||
|
||||
if (gotomaps.containsKey(params[0])) {
|
||||
MapleMap target = c.getChannelServer().getMapFactory().getMap(gotomaps.get(params[0]));
|
||||
|
||||
// expedition issue with this command detected thanks to Masterrulax
|
||||
Portal targetPortal = target.getRandomPlayerSpawnpoint();
|
||||
player.saveLocationOnWarp();
|
||||
player.changeMap(target, targetPortal);
|
||||
} else {
|
||||
// detailed info on goto available areas suggested thanks to Vcoc
|
||||
String sendStr = "Area '#r" + params[0] + "#k' is not available. Available areas:\r\n\r\n#rTowns:#k" + GOTO_TOWNS_INFO;
|
||||
if (player.isGM()) {
|
||||
sendStr += ("\r\n#rAreas:#k\r\n" + GOTO_AREAS_INFO);
|
||||
}
|
||||
|
||||
player.getAbstractPlayerInteraction().npcTalk(NpcId.SPINEL, sendStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
46
src/main/java/client/command/commands/gm1/MobHpCommand.java
Normal file
46
src/main/java/client/command/commands/gm1/MobHpCommand.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm1;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.life.Monster;
|
||||
|
||||
public class MobHpCommand extends Command {
|
||||
{
|
||||
setDescription("Show HP of mobs on current map.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
for (Monster monster : player.getMap().getAllMonsters()) {
|
||||
if (monster != null && monster.getHp() > 0) {
|
||||
player.yellowMessage(monster.getName() + " (" + monster.getId() + ") has " + monster.getHp() + " / " + monster.getMaxHp() + " HP.");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm1;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.id.NpcId;
|
||||
import server.ItemInformationProvider;
|
||||
import server.life.MonsterDropEntry;
|
||||
import server.life.MonsterInformationProvider;
|
||||
import tools.Pair;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class WhatDropsFromCommand extends Command {
|
||||
{
|
||||
setDescription("Show what items drop from a mob.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.dropMessage(5, "Please do @whatdropsfrom <monster name>");
|
||||
return;
|
||||
}
|
||||
String monsterName = player.getLastCommandMessage();
|
||||
String output = "";
|
||||
int limit = 3;
|
||||
Iterator<Pair<Integer, String>> listIterator = MonsterInformationProvider.getMobsIDsFromName(monsterName).iterator();
|
||||
for (int i = 0; i < limit; i++) {
|
||||
if (listIterator.hasNext()) {
|
||||
Pair<Integer, String> data = listIterator.next();
|
||||
int mobId = data.getLeft();
|
||||
String mobName = data.getRight();
|
||||
output += mobName + " drops the following items:\r\n\r\n";
|
||||
for (MonsterDropEntry drop : MonsterInformationProvider.getInstance().retrieveDrop(mobId)) {
|
||||
try {
|
||||
String name = ItemInformationProvider.getInstance().getName(drop.itemId);
|
||||
if (name == null || name.equals("null") || drop.chance == 0) {
|
||||
continue;
|
||||
}
|
||||
float chance = Math.max(1000000 / drop.chance / (!MonsterInformationProvider.getInstance().isBoss(mobId) ? player.getDropRate() : player.getBossDropRate()), 1);
|
||||
output += "- " + name + " (1/" + (int) chance + ")\r\n";
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
output += "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
c.getAbstractPlayerInteraction().npcTalk(NpcId.MAPLE_ADMINISTRATOR, output);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm1;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.id.NpcId;
|
||||
import server.ItemInformationProvider;
|
||||
import server.life.MonsterInformationProvider;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.Pair;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class WhoDropsCommand extends Command {
|
||||
{
|
||||
setDescription("Show what drops an item.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.dropMessage(5, "Please do @whodrops <item name>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (c.tryacquireClient()) {
|
||||
try {
|
||||
String searchString = player.getLastCommandMessage();
|
||||
String output = "";
|
||||
Iterator<Pair<Integer, String>> listIterator = ItemInformationProvider.getInstance().getItemDataByName(searchString).iterator();
|
||||
if (listIterator.hasNext()) {
|
||||
int count = 1;
|
||||
while (listIterator.hasNext() && count <= 3) {
|
||||
Pair<Integer, String> data = listIterator.next();
|
||||
output += "#b" + data.getRight() + "#k is dropped by:\r\n";
|
||||
try (Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT dropperid FROM drop_data WHERE itemid = ? LIMIT 50")) {
|
||||
ps.setInt(1, data.getLeft());
|
||||
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
String resultName = MonsterInformationProvider.getInstance().getMobNameFromId(rs.getInt("dropperid"));
|
||||
if (resultName != null) {
|
||||
output += resultName + ", ";
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
player.dropMessage(6, "There was a problem retrieving the required data. Please try again.");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
output += "\r\n\r\n";
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
player.dropMessage(5, "The item you searched for doesn't exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
c.getAbstractPlayerInteraction().npcTalk(NpcId.MAPLE_ADMINISTRATOR, output);
|
||||
} finally {
|
||||
c.releaseClient();
|
||||
}
|
||||
} else {
|
||||
player.dropMessage(5, "Please wait a while for your request to be processed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
69
src/main/java/client/command/commands/gm2/ApCommand.java
Normal file
69
src/main/java/client/command/commands/gm2/ApCommand.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class ApCommand extends Command {
|
||||
{
|
||||
setDescription("Set available AP.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !ap [<playername>] <newap>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.length < 2) {
|
||||
int newAp = Integer.parseInt(params[0]);
|
||||
if (newAp < 0) {
|
||||
newAp = 0;
|
||||
} else if (newAp > YamlConfig.config.server.MAX_AP) {
|
||||
newAp = YamlConfig.config.server.MAX_AP;
|
||||
}
|
||||
|
||||
player.changeRemainingAp(newAp, false);
|
||||
} else {
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim != null) {
|
||||
int newAp = Integer.parseInt(params[1]);
|
||||
if (newAp < 0) {
|
||||
newAp = 0;
|
||||
} else if (newAp > YamlConfig.config.server.MAX_AP) {
|
||||
newAp = YamlConfig.config.server.MAX_AP;
|
||||
}
|
||||
|
||||
victim.changeRemainingAp(newAp, false);
|
||||
} else {
|
||||
player.message("Player '" + params[0] + "' could not be found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
54
src/main/java/client/command/commands/gm2/BombCommand.java
Normal file
54
src/main/java/client/command/commands/gm2/BombCommand.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.id.MobId;
|
||||
import net.server.Server;
|
||||
import server.life.LifeFactory;
|
||||
import tools.PacketCreator;
|
||||
|
||||
public class BombCommand extends Command {
|
||||
{
|
||||
setDescription("Bomb a player, dealing damage.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length > 0) {
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim != null) {
|
||||
victim.getMap().spawnMonsterOnGroundBelow(LifeFactory.getMonster(MobId.ARPQ_BOMB), victim.getPosition());
|
||||
Server.getInstance().broadcastGMMessage(c.getWorld(), PacketCreator.serverNotice(5, player.getName() + " used !bomb on " + victim.getName()));
|
||||
} else {
|
||||
player.message("Player '" + params[0] + "' could not be found on this world.");
|
||||
}
|
||||
} else {
|
||||
player.getMap().spawnMonsterOnGroundBelow(LifeFactory.getMonster(MobId.ARPQ_BOMB), player.getPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
51
src/main/java/client/command/commands/gm2/BuffCommand.java
Normal file
51
src/main/java/client/command/commands/gm2/BuffCommand.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
|
||||
public class BuffCommand extends Command {
|
||||
{
|
||||
setDescription("Activate a buff.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !buff <buffid>");
|
||||
return;
|
||||
}
|
||||
int skillid = Integer.parseInt(params[0]);
|
||||
|
||||
Skill skill = SkillFactory.getSkill(skillid);
|
||||
if (skill != null) {
|
||||
skill.getEffect(skill.getMaxLevel()).applyTo(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
|
||||
public class BuffMapCommand extends Command {
|
||||
{
|
||||
setDescription("Give GM buffs to the whole map.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
SkillFactory.getSkill(9101001).getEffect(SkillFactory.getSkill(9101001).getMaxLevel()).applyTo(player, true);
|
||||
SkillFactory.getSkill(9101002).getEffect(SkillFactory.getSkill(9101002).getMaxLevel()).applyTo(player, true);
|
||||
SkillFactory.getSkill(9101003).getEffect(SkillFactory.getSkill(9101003).getMaxLevel()).applyTo(player, true);
|
||||
SkillFactory.getSkill(9101008).getEffect(SkillFactory.getSkill(9101008).getMaxLevel()).applyTo(player, true);
|
||||
SkillFactory.getSkill(1005).getEffect(SkillFactory.getSkill(1005).getMaxLevel()).applyTo(player, true);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class ClearDropsCommand extends Command {
|
||||
{
|
||||
setDescription("Clear drops by player.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
player.getMap().clearDrops(player);
|
||||
player.dropMessage(5, "Cleared dropped items");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.maps.SavedLocationType;
|
||||
|
||||
public class ClearSavedLocationsCommand extends Command {
|
||||
{
|
||||
setDescription("Clear saved locations for a player.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer(), victim;
|
||||
|
||||
if (params.length > 0) {
|
||||
victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim == null) {
|
||||
player.message("Player '" + params[0] + "' could not be found.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
victim = c.getPlayer();
|
||||
}
|
||||
|
||||
for (SavedLocationType type : SavedLocationType.values()) {
|
||||
victim.clearSavedLocation(type);
|
||||
}
|
||||
|
||||
player.message("Cleared " + params[0] + "'s saved locations.");
|
||||
}
|
||||
}
|
||||
140
src/main/java/client/command/commands/gm2/ClearSlotCommand.java
Normal file
140
src/main/java/client/command/commands/gm2/ClearSlotCommand.java
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.inventory.InventoryType;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.manipulator.InventoryManipulator;
|
||||
|
||||
public class ClearSlotCommand extends Command {
|
||||
{
|
||||
setDescription("Clear all items in an inventory tab.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !clearslot <all, equip, use, setup, etc or cash.>");
|
||||
return;
|
||||
}
|
||||
String type = params[0];
|
||||
switch (type) {
|
||||
case "all":
|
||||
for (int i = 0; i < 101; i++) {
|
||||
Item tempItem = c.getPlayer().getInventory(InventoryType.EQUIP).getItem((byte) i);
|
||||
if (tempItem == null) {
|
||||
continue;
|
||||
}
|
||||
InventoryManipulator.removeFromSlot(c, InventoryType.EQUIP, (byte) i, tempItem.getQuantity(), false, false);
|
||||
}
|
||||
for (int i = 0; i < 101; i++) {
|
||||
Item tempItem = c.getPlayer().getInventory(InventoryType.USE).getItem((byte) i);
|
||||
if (tempItem == null) {
|
||||
continue;
|
||||
}
|
||||
InventoryManipulator.removeFromSlot(c, InventoryType.USE, (byte) i, tempItem.getQuantity(), false, false);
|
||||
}
|
||||
for (int i = 0; i < 101; i++) {
|
||||
Item tempItem = c.getPlayer().getInventory(InventoryType.ETC).getItem((byte) i);
|
||||
if (tempItem == null) {
|
||||
continue;
|
||||
}
|
||||
InventoryManipulator.removeFromSlot(c, InventoryType.ETC, (byte) i, tempItem.getQuantity(), false, false);
|
||||
}
|
||||
for (int i = 0; i < 101; i++) {
|
||||
Item tempItem = c.getPlayer().getInventory(InventoryType.SETUP).getItem((byte) i);
|
||||
if (tempItem == null) {
|
||||
continue;
|
||||
}
|
||||
InventoryManipulator.removeFromSlot(c, InventoryType.SETUP, (byte) i, tempItem.getQuantity(), false, false);
|
||||
}
|
||||
for (int i = 0; i < 101; i++) {
|
||||
Item tempItem = c.getPlayer().getInventory(InventoryType.CASH).getItem((byte) i);
|
||||
if (tempItem == null) {
|
||||
continue;
|
||||
}
|
||||
InventoryManipulator.removeFromSlot(c, InventoryType.CASH, (byte) i, tempItem.getQuantity(), false, false);
|
||||
}
|
||||
player.yellowMessage("All Slots Cleared.");
|
||||
break;
|
||||
case "equip":
|
||||
for (int i = 0; i < 101; i++) {
|
||||
Item tempItem = c.getPlayer().getInventory(InventoryType.EQUIP).getItem((byte) i);
|
||||
if (tempItem == null) {
|
||||
continue;
|
||||
}
|
||||
InventoryManipulator.removeFromSlot(c, InventoryType.EQUIP, (byte) i, tempItem.getQuantity(), false, false);
|
||||
}
|
||||
player.yellowMessage("Equipment Slot Cleared.");
|
||||
break;
|
||||
case "use":
|
||||
for (int i = 0; i < 101; i++) {
|
||||
Item tempItem = c.getPlayer().getInventory(InventoryType.USE).getItem((byte) i);
|
||||
if (tempItem == null) {
|
||||
continue;
|
||||
}
|
||||
InventoryManipulator.removeFromSlot(c, InventoryType.USE, (byte) i, tempItem.getQuantity(), false, false);
|
||||
}
|
||||
player.yellowMessage("Use Slot Cleared.");
|
||||
break;
|
||||
case "setup":
|
||||
for (int i = 0; i < 101; i++) {
|
||||
Item tempItem = c.getPlayer().getInventory(InventoryType.SETUP).getItem((byte) i);
|
||||
if (tempItem == null) {
|
||||
continue;
|
||||
}
|
||||
InventoryManipulator.removeFromSlot(c, InventoryType.SETUP, (byte) i, tempItem.getQuantity(), false, false);
|
||||
}
|
||||
player.yellowMessage("Set-Up Slot Cleared.");
|
||||
break;
|
||||
case "etc":
|
||||
for (int i = 0; i < 101; i++) {
|
||||
Item tempItem = c.getPlayer().getInventory(InventoryType.ETC).getItem((byte) i);
|
||||
if (tempItem == null) {
|
||||
continue;
|
||||
}
|
||||
InventoryManipulator.removeFromSlot(c, InventoryType.ETC, (byte) i, tempItem.getQuantity(), false, false);
|
||||
}
|
||||
player.yellowMessage("ETC Slot Cleared.");
|
||||
break;
|
||||
case "cash":
|
||||
for (int i = 0; i < 101; i++) {
|
||||
Item tempItem = c.getPlayer().getInventory(InventoryType.CASH).getItem((byte) i);
|
||||
if (tempItem == null) {
|
||||
continue;
|
||||
}
|
||||
InventoryManipulator.removeFromSlot(c, InventoryType.CASH, (byte) i, tempItem.getQuantity(), false, false);
|
||||
}
|
||||
player.yellowMessage("Cash Slot Cleared.");
|
||||
break;
|
||||
default:
|
||||
player.yellowMessage("Slot" + type + " does not exist!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
65
src/main/java/client/command/commands/gm2/DcCommand.java
Normal file
65
src/main/java/client/command/commands/gm2/DcCommand.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class DcCommand extends Command {
|
||||
{
|
||||
setDescription("Disconnect a player.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !dc <playername>");
|
||||
return;
|
||||
}
|
||||
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim == null) {
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim == null) {
|
||||
victim = player.getMap().getCharacterByName(params[0]);
|
||||
if (victim != null) {
|
||||
try {//sometimes bugged because the map = null
|
||||
victim.getClient().disconnect(true, false);
|
||||
player.getMap().removePlayer(victim);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (player.gmLevel() < victim.gmLevel()) {
|
||||
victim = player;
|
||||
}
|
||||
victim.getClient().disconnect(false, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
|
||||
public class EmpowerMeCommand extends Command {
|
||||
{
|
||||
setDescription("Activate all useful buffs.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
final int[] array = {2311003, 2301004, 1301007, 4101004, 2001002, 1101007, 1005, 2301003, 5121009, 1111002, 4111001, 4111002, 4211003, 4211005, 1321000, 2321004, 3121002};
|
||||
for (int i : array) {
|
||||
SkillFactory.getSkill(i).getEffect(SkillFactory.getSkill(i).getMaxLevel()).applyTo(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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 client.command.commands.gm2;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class GachaListCommand extends Command {
|
||||
{
|
||||
setDescription("Show gachapon rewards.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
c.getAbstractPlayerInteraction().openNpc(10000, "gachaponInfo");
|
||||
}
|
||||
}
|
||||
39
src/main/java/client/command/commands/gm2/GmShopCommand.java
Normal file
39
src/main/java/client/command/commands/gm2/GmShopCommand.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.ShopFactory;
|
||||
|
||||
public class GmShopCommand extends Command {
|
||||
{
|
||||
setDescription("Open the GM shop.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
ShopFactory.getInstance().getShop(1337).sendShop(c);
|
||||
}
|
||||
}
|
||||
41
src/main/java/client/command/commands/gm2/HealCommand.java
Normal file
41
src/main/java/client/command/commands/gm2/HealCommand.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class HealCommand extends Command {
|
||||
{
|
||||
setDescription("Fully heal your HP/MP.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
player.healHpMp();
|
||||
}
|
||||
|
||||
}
|
||||
42
src/main/java/client/command/commands/gm2/HideCommand.java
Normal file
42
src/main/java/client/command/commands/gm2/HideCommand.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
|
||||
public class HideCommand extends Command {
|
||||
{
|
||||
setDescription("Hide from players.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
SkillFactory.getSkill(9101004).getEffect(SkillFactory.getSkill(9101004).getMaxLevel()).applyTo(player);
|
||||
|
||||
}
|
||||
}
|
||||
139
src/main/java/client/command/commands/gm2/IdCommand.java
Normal file
139
src/main/java/client/command/commands/gm2/IdCommand.java
Normal file
@@ -0,0 +1,139 @@
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.game.NpcChat;
|
||||
import constants.id.NpcId;
|
||||
import server.ThreadManager;
|
||||
import tools.exceptions.IdTypeNotSupportedException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class IdCommand extends Command {
|
||||
{
|
||||
setDescription("Search in handbook.");
|
||||
}
|
||||
private final static int MAX_SEARCH_HITS = 100;
|
||||
private final Map<String, String> handbookDirectory = typeFilePaths();
|
||||
private final Map<String, HandbookFileItems> typeItems = new ConcurrentHashMap<>();
|
||||
|
||||
private Map<String, String> typeFilePaths() {
|
||||
return Map.ofEntries(
|
||||
Map.entry("map", "handbook/Map.txt"),
|
||||
Map.entry("etc", "handbook/Etc.txt"),
|
||||
Map.entry("npc", "handbook/NPC.txt"),
|
||||
Map.entry("use", "handbook/Use.txt"),
|
||||
Map.entry("weapon", "handbook/Equip/Weapon.txt") // TODO add more into this
|
||||
);
|
||||
}
|
||||
|
||||
private static class HandbookFileItems {
|
||||
private final List<HandbookItem> items;
|
||||
|
||||
public HandbookFileItems(List<String> fileLines) {
|
||||
this.items = fileLines.stream()
|
||||
.map(this::parseLine)
|
||||
.filter(Predicate.not(Objects::isNull))
|
||||
.toList();
|
||||
}
|
||||
|
||||
private HandbookItem parseLine(String line) {
|
||||
if (line == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] splitLine = line.split(" - ", 2);
|
||||
if (splitLine.length < 2 || splitLine[1].isBlank()) {
|
||||
return null;
|
||||
}
|
||||
return new HandbookItem(splitLine[0], splitLine[1]);
|
||||
}
|
||||
|
||||
public List<HandbookItem> search(String query) {
|
||||
if (query == null || query.isBlank()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return items.stream()
|
||||
.filter(item -> item.matches(query))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
private record HandbookItem(String id, String name) {
|
||||
|
||||
public HandbookItem {
|
||||
Objects.requireNonNull(id);
|
||||
Objects.requireNonNull(name);
|
||||
}
|
||||
|
||||
public boolean matches(String query) {
|
||||
if (query == null) {
|
||||
return false;
|
||||
}
|
||||
return this.name.toLowerCase().contains(query.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, final String[] params) {
|
||||
final Character chr = client.getPlayer();
|
||||
if (params.length < 2) {
|
||||
chr.yellowMessage("Syntax: !id <type> <query>");
|
||||
return;
|
||||
}
|
||||
final String type = params[0].toLowerCase();
|
||||
final String[] queryItems = Arrays.copyOfRange(params, 1, params.length);
|
||||
final String query = String.join(" ", queryItems);
|
||||
chr.yellowMessage("Querying for entry... May take some time... Please try to refine your search.");
|
||||
Runnable queryRunnable = () -> {
|
||||
try {
|
||||
populateIdMap(type);
|
||||
|
||||
final HandbookFileItems handbookFileItems = typeItems.get(type);
|
||||
if (handbookFileItems == null) {
|
||||
return;
|
||||
}
|
||||
final List<HandbookItem> searchHits = handbookFileItems.search(query);
|
||||
|
||||
if (!searchHits.isEmpty()) {
|
||||
String searchHitsText = searchHits.stream()
|
||||
.limit(MAX_SEARCH_HITS)
|
||||
.map(item -> "Id for %s is: #b%s#k".formatted(item.name, item.id))
|
||||
.collect(Collectors.joining(NpcChat.NEW_LINE));
|
||||
int hitsCount = Math.min(searchHits.size(), MAX_SEARCH_HITS);
|
||||
String summaryText = "Results found: #r%d#k | Returned: #b%d#k/100 | Refine search query to improve time.".formatted(searchHits.size(), hitsCount);
|
||||
String fullText = searchHitsText + NpcChat.NEW_LINE + summaryText;
|
||||
chr.getAbstractPlayerInteraction().npcTalk(NpcId.MAPLE_ADMINISTRATOR, fullText);
|
||||
} else {
|
||||
chr.yellowMessage(String.format("Id not found for item: %s, of type: %s.", query, type));
|
||||
}
|
||||
} catch (IdTypeNotSupportedException e) {
|
||||
chr.yellowMessage("Your query type is not supported.");
|
||||
} catch (IOException e) {
|
||||
chr.yellowMessage("Error reading file, please contact your administrator.");
|
||||
}
|
||||
};
|
||||
|
||||
ThreadManager.getInstance().newTask(queryRunnable);
|
||||
}
|
||||
|
||||
private void populateIdMap(String type) throws IdTypeNotSupportedException, IOException {
|
||||
final String filePath = handbookDirectory.get(type);
|
||||
if (filePath == null) {
|
||||
throw new IdTypeNotSupportedException();
|
||||
}
|
||||
if (typeItems.containsKey(type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<String> fileLines = Files.readAllLines(Path.of(filePath));
|
||||
typeItems.put(type, new HandbookFileItems(fileLines));
|
||||
}
|
||||
}
|
||||
92
src/main/java/client/command/commands/gm2/ItemCommand.java
Normal file
92
src/main/java/client/command/commands/gm2/ItemCommand.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.inventory.Pet;
|
||||
import client.inventory.manipulator.InventoryManipulator;
|
||||
import config.YamlConfig;
|
||||
import constants.inventory.ItemConstants;
|
||||
import server.ItemInformationProvider;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.DAYS;
|
||||
|
||||
public class ItemCommand extends Command {
|
||||
{
|
||||
setDescription("Spawn an item into your inventory.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !item <itemid> <quantity>");
|
||||
return;
|
||||
}
|
||||
|
||||
int itemId = Integer.parseInt(params[0]);
|
||||
ItemInformationProvider ii = ItemInformationProvider.getInstance();
|
||||
|
||||
if (ii.getName(itemId) == null) {
|
||||
player.yellowMessage("Item id '" + params[0] + "' does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
short quantity = 1;
|
||||
if (params.length >= 2) {
|
||||
quantity = Short.parseShort(params[1]);
|
||||
}
|
||||
|
||||
if (YamlConfig.config.server.BLOCK_GENERATE_CASH_ITEM && ii.isCash(itemId)) {
|
||||
player.yellowMessage("You cannot create a cash item with this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ItemConstants.isPet(itemId)) {
|
||||
if (params.length >= 2) { // thanks to istreety & TacoBell
|
||||
quantity = 1;
|
||||
long days = Math.max(1, Integer.parseInt(params[1]));
|
||||
long expiration = System.currentTimeMillis() + DAYS.toMillis(days);
|
||||
int petid = Pet.createPet(itemId);
|
||||
|
||||
InventoryManipulator.addById(c, itemId, quantity, player.getName(), petid, expiration);
|
||||
return;
|
||||
} else {
|
||||
player.yellowMessage("Pet Syntax: !item <itemid> <expiration>");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
short flag = 0;
|
||||
if (player.gmLevel() < 3) {
|
||||
flag |= ItemConstants.ACCOUNT_SHARING;
|
||||
flag |= ItemConstants.UNTRADEABLE;
|
||||
}
|
||||
|
||||
InventoryManipulator.addById(c, itemId, quantity, player.getName(), -1, flag, -1);
|
||||
}
|
||||
}
|
||||
120
src/main/java/client/command/commands/gm2/ItemDropCommand.java
Normal file
120
src/main/java/client/command/commands/gm2/ItemDropCommand.java
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.inventory.InventoryType;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.Pet;
|
||||
import config.YamlConfig;
|
||||
import constants.inventory.ItemConstants;
|
||||
import server.ItemInformationProvider;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.DAYS;
|
||||
|
||||
public class ItemDropCommand extends Command {
|
||||
{
|
||||
setDescription("Spawn an item onto the ground.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !drop <itemid> <quantity>");
|
||||
return;
|
||||
}
|
||||
|
||||
int itemId = Integer.parseInt(params[0]);
|
||||
ItemInformationProvider ii = ItemInformationProvider.getInstance();
|
||||
|
||||
if (ii.getName(itemId) == null) {
|
||||
player.yellowMessage("Item id '" + params[0] + "' does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
short quantity = 1;
|
||||
if (params.length >= 2) {
|
||||
quantity = Short.parseShort(params[1]);
|
||||
}
|
||||
|
||||
if (YamlConfig.config.server.BLOCK_GENERATE_CASH_ITEM && ii.isCash(itemId)) {
|
||||
player.yellowMessage("You cannot create a cash item with this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ItemConstants.isPet(itemId)) {
|
||||
if (params.length >= 2) { // thanks to istreety & TacoBell
|
||||
quantity = 1;
|
||||
long days = Math.max(1, Integer.parseInt(params[1]));
|
||||
long expiration = System.currentTimeMillis() + DAYS.toMillis(days);
|
||||
int petid = Pet.createPet(itemId);
|
||||
|
||||
Item toDrop = new Item(itemId, (short) 0, quantity, petid);
|
||||
toDrop.setExpiration(expiration);
|
||||
|
||||
toDrop.setOwner("");
|
||||
if (player.gmLevel() < 3) {
|
||||
short f = toDrop.getFlag();
|
||||
f |= ItemConstants.ACCOUNT_SHARING;
|
||||
f |= ItemConstants.UNTRADEABLE;
|
||||
f |= ItemConstants.SANDBOX;
|
||||
|
||||
toDrop.setFlag(f);
|
||||
toDrop.setOwner("TRIAL-MODE");
|
||||
}
|
||||
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), toDrop, c.getPlayer().getPosition(), true, true);
|
||||
|
||||
return;
|
||||
} else {
|
||||
player.yellowMessage("Pet Syntax: !drop <itemid> <expiration>");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Item toDrop;
|
||||
if (ItemConstants.getInventoryType(itemId) == InventoryType.EQUIP) {
|
||||
toDrop = ii.getEquipById(itemId);
|
||||
} else {
|
||||
toDrop = new Item(itemId, (short) 0, quantity);
|
||||
}
|
||||
|
||||
toDrop.setOwner(player.getName());
|
||||
if (player.gmLevel() < 3) {
|
||||
short f = toDrop.getFlag();
|
||||
f |= ItemConstants.ACCOUNT_SHARING;
|
||||
f |= ItemConstants.UNTRADEABLE;
|
||||
f |= ItemConstants.SANDBOX;
|
||||
|
||||
toDrop.setFlag(f);
|
||||
toDrop.setOwner("TRIAL-MODE");
|
||||
}
|
||||
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), toDrop, c.getPlayer().getPosition(), true, true);
|
||||
}
|
||||
}
|
||||
75
src/main/java/client/command/commands/gm2/JailCommand.java
Normal file
75
src/main/java/client/command/commands/gm2/JailCommand.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.id.MapId;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.Portal;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||
|
||||
public class JailCommand extends Command {
|
||||
{
|
||||
setDescription("Move a player to the jail.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !jail <playername> [<minutes>]");
|
||||
return;
|
||||
}
|
||||
|
||||
int minutesJailed = 5;
|
||||
if (params.length >= 2) {
|
||||
minutesJailed = Integer.parseInt(params[1]);
|
||||
if (minutesJailed <= 0) {
|
||||
player.yellowMessage("Syntax: !jail <playername> [<minutes>]");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim != null) {
|
||||
victim.addJailExpirationTime(MINUTES.toMillis(minutesJailed));
|
||||
|
||||
if (victim.getMapId() != MapId.JAIL) { // those gone to jail won't be changing map anyway
|
||||
MapleMap target = c.getChannelServer().getMapFactory().getMap(MapId.JAIL);
|
||||
Portal targetPortal = target.getPortal(0);
|
||||
victim.saveLocationOnWarp();
|
||||
victim.changeMap(target, targetPortal);
|
||||
player.message(victim.getName() + " was jailed for " + minutesJailed + " minutes.");
|
||||
} else {
|
||||
player.message(victim.getName() + "'s time in jail has been extended for " + minutesJailed + " minutes.");
|
||||
}
|
||||
|
||||
} else {
|
||||
player.message("Player '" + params[0] + "' could not be found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/main/java/client/command/commands/gm2/JobCommand.java
Normal file
67
src/main/java/client/command/commands/gm2/JobCommand.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.Job;
|
||||
import client.command.Command;
|
||||
|
||||
public class JobCommand extends Command {
|
||||
{
|
||||
setDescription("Change job of a player.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length == 1) {
|
||||
int jobid = Integer.parseInt(params[0]);
|
||||
if (jobid < 0 || jobid >= 2200) {
|
||||
player.message("Jobid " + jobid + " is not available.");
|
||||
return;
|
||||
}
|
||||
|
||||
player.changeJob(Job.getById(jobid));
|
||||
player.equipChanged();
|
||||
} else if (params.length == 2) {
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
|
||||
if (victim != null) {
|
||||
int jobid = Integer.parseInt(params[1]);
|
||||
if (jobid < 0 || jobid >= 2200) {
|
||||
player.message("Jobid " + jobid + " is not available.");
|
||||
return;
|
||||
}
|
||||
|
||||
victim.changeJob(Job.getById(jobid));
|
||||
player.equipChanged();
|
||||
} else {
|
||||
player.message("Player '" + params[0] + "' could not be found.");
|
||||
}
|
||||
} else {
|
||||
player.message("Syntax: !job <job id> <opt: IGN of another person>");
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/main/java/client/command/commands/gm2/LevelCommand.java
Normal file
55
src/main/java/client/command/commands/gm2/LevelCommand.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class LevelCommand extends Command {
|
||||
{
|
||||
setDescription("Set your level.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !level <newlevel>");
|
||||
return;
|
||||
}
|
||||
|
||||
player.loseExp(player.getExp(), false, false);
|
||||
player.setLevel(Math.min(Integer.parseInt(params[0]), player.getMaxClassLevel()) - 1);
|
||||
|
||||
player.resetPlayerRates();
|
||||
if (YamlConfig.config.server.USE_ADD_RATES_BY_LEVEL) {
|
||||
player.setPlayerRates();
|
||||
}
|
||||
player.setWorldRates();
|
||||
|
||||
player.levelUp(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class LevelProCommand extends Command {
|
||||
{
|
||||
setDescription("Set your level, one by one.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !levelpro <newlevel>");
|
||||
return;
|
||||
}
|
||||
while (player.getLevel() < Math.min(player.getMaxClassLevel(), Integer.parseInt(params[0]))) {
|
||||
player.levelUp(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
52
src/main/java/client/command/commands/gm2/LootCommand.java
Normal file
52
src/main/java/client/command/commands/gm2/LootCommand.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Resinate
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.maps.MapItem;
|
||||
import server.maps.MapObject;
|
||||
import server.maps.MapObjectType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class LootCommand extends Command {
|
||||
|
||||
{
|
||||
setDescription("Loots all items that belong to you.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
List<MapObject> items = c.getPlayer().getMap().getMapObjectsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapObjectType.ITEM));
|
||||
for (MapObject item : items) {
|
||||
MapItem mapItem = (MapItem) item;
|
||||
if (mapItem.getOwnerId() == c.getPlayer().getId() || mapItem.getOwnerId() == c.getPlayer().getPartyId()) {
|
||||
c.getPlayer().pickupItem(mapItem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.*;
|
||||
import client.command.Command;
|
||||
import provider.Data;
|
||||
import provider.DataProviderFactory;
|
||||
import provider.wz.WZFiles;
|
||||
|
||||
public class MaxSkillCommand extends Command {
|
||||
{
|
||||
setDescription("Max out all job skills.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
for (Data skill_ : DataProviderFactory.getDataProvider(WZFiles.STRING).getData("Skill.img").getChildren()) {
|
||||
try {
|
||||
Skill skill = SkillFactory.getSkill(Integer.parseInt(skill_.getName()));
|
||||
player.changeSkillLevel(skill, (byte) skill.getMaxLevel(), skill.getMaxLevel(), -1);
|
||||
} catch (NumberFormatException nfe) {
|
||||
nfe.printStackTrace();
|
||||
break;
|
||||
} catch (NullPointerException npe) {
|
||||
}
|
||||
}
|
||||
|
||||
if (player.getJob().isA(Job.ARAN1) || player.getJob().isA(Job.LEGEND)) {
|
||||
Skill skill = SkillFactory.getSkill(5001005);
|
||||
player.changeSkillLevel(skill, (byte) -1, -1, -1);
|
||||
} else {
|
||||
Skill skill = SkillFactory.getSkill(21001001);
|
||||
player.changeSkillLevel(skill, (byte) -1, -1, -1);
|
||||
}
|
||||
|
||||
player.yellowMessage("Skills maxed out.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.Stat;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class MaxStatCommand extends Command {
|
||||
{
|
||||
setDescription("Max out all character stats.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
player.loseExp(player.getExp(), false, false);
|
||||
player.setLevel(255);
|
||||
player.resetPlayerRates();
|
||||
if (YamlConfig.config.server.USE_ADD_RATES_BY_LEVEL) {
|
||||
player.setPlayerRates();
|
||||
}
|
||||
player.setWorldRates();
|
||||
player.updateStrDexIntLuk(Short.MAX_VALUE);
|
||||
player.setFame(13337);
|
||||
player.updateMaxHpMaxMp(30000, 30000);
|
||||
player.updateSingleStat(Stat.LEVEL, 255);
|
||||
player.updateSingleStat(Stat.FAME, 13337);
|
||||
player.yellowMessage("Stats maxed out.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.life.MobSkill;
|
||||
import server.life.MobSkillFactory;
|
||||
import server.life.MobSkillType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
public class MobSkillCommand extends Command {
|
||||
{
|
||||
setDescription("Apply a mob skill to all mobs on the map. Args: <mob skill id> <skill level>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
if (params.length < 2) {
|
||||
throw new IllegalArgumentException("Mob skill command requires two args: mob skill id and level");
|
||||
}
|
||||
|
||||
String skillId = params[0];
|
||||
String skillLevel = params[1];
|
||||
Optional<MobSkillType> possibleType = MobSkillType.from(Integer.parseInt(skillId));
|
||||
Optional<MobSkill> possibleSkill = possibleType.map(
|
||||
type -> MobSkillFactory.getMobSkillOrThrow(type, Integer.parseInt(skillLevel))
|
||||
);
|
||||
if (possibleSkill.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Character chr = client.getPlayer();
|
||||
MobSkill mobSkill = possibleSkill.get();
|
||||
chr.getMap().getAllMonsters().forEach(
|
||||
monster -> mobSkill.applyEffect(chr, monster, false, Collections.emptyList())
|
||||
);
|
||||
}
|
||||
}
|
||||
57
src/main/java/client/command/commands/gm2/ReachCommand.java
Normal file
57
src/main/java/client/command/commands/gm2/ReachCommand.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.maps.MapleMap;
|
||||
|
||||
public class ReachCommand extends Command {
|
||||
{
|
||||
setDescription("Warp to a player.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !reach <playername>");
|
||||
return;
|
||||
}
|
||||
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim != null && victim.isLoggedin()) {
|
||||
if (player.getClient().getChannel() != victim.getClient().getChannel()) {
|
||||
player.dropMessage(5, "Player '" + victim.getName() + "' is at channel " + victim.getClient().getChannel() + ".");
|
||||
} else {
|
||||
MapleMap map = victim.getMap();
|
||||
player.saveLocationOnWarp();
|
||||
player.forceChangeMap(map, map.findClosestPortal(victim.getPosition()));
|
||||
}
|
||||
} else {
|
||||
player.dropMessage(6, "Unknown player.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.inventory.InventoryType;
|
||||
import client.inventory.Item;
|
||||
import constants.inventory.ItemConstants;
|
||||
import server.ItemInformationProvider;
|
||||
|
||||
public class RechargeCommand extends Command {
|
||||
{
|
||||
setDescription("Recharge and refill all USE items.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
ItemInformationProvider ii = ItemInformationProvider.getInstance();
|
||||
for (Item torecharge : c.getPlayer().getInventory(InventoryType.USE).list()) {
|
||||
if (ItemConstants.isThrowingStar(torecharge.getItemId())) {
|
||||
torecharge.setQuantity(ii.getSlotMax(c, torecharge.getItemId()));
|
||||
c.getPlayer().forceUpdateItem(torecharge);
|
||||
} else if (ItemConstants.isArrow(torecharge.getItemId())) {
|
||||
torecharge.setQuantity(ii.getSlotMax(c, torecharge.getItemId()));
|
||||
c.getPlayer().forceUpdateItem(torecharge);
|
||||
} else if (ItemConstants.isBullet(torecharge.getItemId())) {
|
||||
torecharge.setQuantity(ii.getSlotMax(c, torecharge.getItemId()));
|
||||
c.getPlayer().forceUpdateItem(torecharge);
|
||||
} else if (ItemConstants.isConsumable(torecharge.getItemId())) {
|
||||
torecharge.setQuantity(ii.getSlotMax(c, torecharge.getItemId()));
|
||||
c.getPlayer().forceUpdateItem(torecharge);
|
||||
}
|
||||
}
|
||||
player.dropMessage(5, "USE Recharged.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.*;
|
||||
import client.command.Command;
|
||||
import provider.Data;
|
||||
import provider.DataProviderFactory;
|
||||
import provider.wz.WZFiles;
|
||||
|
||||
public class ResetSkillCommand extends Command {
|
||||
{
|
||||
setDescription("Set all skill levels to 0.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
for (Data skill_ : DataProviderFactory.getDataProvider(WZFiles.STRING).getData("Skill.img").getChildren()) {
|
||||
try {
|
||||
Skill skill = SkillFactory.getSkill(Integer.parseInt(skill_.getName()));
|
||||
player.changeSkillLevel(skill, (byte) 0, skill.getMaxLevel(), -1);
|
||||
} catch (NumberFormatException nfe) {
|
||||
nfe.printStackTrace();
|
||||
break;
|
||||
} catch (NullPointerException npe) {
|
||||
}
|
||||
}
|
||||
|
||||
if (player.getJob().isA(Job.ARAN1) || player.getJob().isA(Job.LEGEND)) {
|
||||
Skill skill = SkillFactory.getSkill(5001005);
|
||||
player.changeSkillLevel(skill, (byte) -1, -1, -1);
|
||||
} else {
|
||||
Skill skill = SkillFactory.getSkill(21001001);
|
||||
player.changeSkillLevel(skill, (byte) -1, -1, -1);
|
||||
}
|
||||
|
||||
player.yellowMessage("Skills reseted.");
|
||||
}
|
||||
}
|
||||
139
src/main/java/client/command/commands/gm2/SearchCommand.java
Normal file
139
src/main/java/client/command/commands/gm2/SearchCommand.java
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import constants.id.NpcId;
|
||||
import provider.Data;
|
||||
import provider.DataProvider;
|
||||
import provider.DataProviderFactory;
|
||||
import provider.DataTool;
|
||||
import provider.wz.WZFiles;
|
||||
import server.ItemInformationProvider;
|
||||
import server.quest.Quest;
|
||||
import tools.Pair;
|
||||
|
||||
public class SearchCommand extends Command {
|
||||
private static Data npcStringData;
|
||||
private static Data mobStringData;
|
||||
private static Data skillStringData;
|
||||
private static Data mapStringData;
|
||||
|
||||
{
|
||||
setDescription("Search String.wz.");
|
||||
|
||||
DataProvider dataProvider = DataProviderFactory.getDataProvider(WZFiles.STRING);
|
||||
npcStringData = dataProvider.getData("Npc.img");
|
||||
mobStringData = dataProvider.getData("Mob.img");
|
||||
skillStringData = dataProvider.getData("Skill.img");
|
||||
mapStringData = dataProvider.getData("Map.img");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 2) {
|
||||
player.yellowMessage("Syntax: !search <type> <name>");
|
||||
return;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
String search = joinStringFrom(params, 1);
|
||||
long start = System.currentTimeMillis();//for the lulz
|
||||
Data data = null;
|
||||
if (!params[0].equalsIgnoreCase("ITEM")) {
|
||||
int searchType = 0;
|
||||
|
||||
if (params[0].equalsIgnoreCase("NPC")) {
|
||||
data = npcStringData;
|
||||
} else if (params[0].equalsIgnoreCase("MOB") || params[0].equalsIgnoreCase("MONSTER")) {
|
||||
data = mobStringData;
|
||||
} else if (params[0].equalsIgnoreCase("SKILL")) {
|
||||
data = skillStringData;
|
||||
} else if (params[0].equalsIgnoreCase("MAP")) {
|
||||
data = mapStringData;
|
||||
searchType = 1;
|
||||
} else if (params[0].equalsIgnoreCase("QUEST")) {
|
||||
data = mapStringData;
|
||||
searchType = 2;
|
||||
} else {
|
||||
sb.append("#bInvalid search.\r\nSyntax: '!search [type] [name]', where [type] is MAP, QUEST, NPC, ITEM, MOB, or SKILL.");
|
||||
}
|
||||
if (data != null) {
|
||||
String name;
|
||||
|
||||
if (searchType == 0) {
|
||||
for (Data searchData : data.getChildren()) {
|
||||
name = DataTool.getString(searchData.getChildByPath("name"), "NO-NAME");
|
||||
if (name.toLowerCase().contains(search.toLowerCase())) {
|
||||
sb.append("#b").append(Integer.parseInt(searchData.getName())).append("#k - #r").append(name).append("\r\n");
|
||||
}
|
||||
}
|
||||
} else if (searchType == 1) {
|
||||
String mapName, streetName;
|
||||
|
||||
for (Data searchDataDir : data.getChildren()) {
|
||||
for (Data searchData : searchDataDir.getChildren()) {
|
||||
mapName = DataTool.getString(searchData.getChildByPath("mapName"), "NO-NAME");
|
||||
streetName = DataTool.getString(searchData.getChildByPath("streetName"), "NO-NAME");
|
||||
|
||||
if (mapName.toLowerCase().contains(search.toLowerCase()) || streetName.toLowerCase().contains(search.toLowerCase())) {
|
||||
sb.append("#b").append(Integer.parseInt(searchData.getName())).append("#k - #r").append(streetName).append(" - ").append(mapName).append("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Quest mq : Quest.getMatchedQuests(search)) {
|
||||
sb.append("#b").append(mq.getId()).append("#k - #r");
|
||||
|
||||
String parentName = mq.getParentName();
|
||||
if (!parentName.isEmpty()) {
|
||||
sb.append(parentName).append(" - ");
|
||||
}
|
||||
sb.append(mq.getName()).append("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Pair<Integer, String> itemPair : ItemInformationProvider.getInstance().getAllItems()) {
|
||||
if (sb.length() < 32654) {//ohlol
|
||||
if (itemPair.getRight().toLowerCase().contains(search.toLowerCase())) {
|
||||
sb.append("#b").append(itemPair.getLeft()).append("#k - #r").append(itemPair.getRight()).append("\r\n");
|
||||
}
|
||||
} else {
|
||||
sb.append("#bCouldn't load all items, there are too many results.\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sb.length() == 0) {
|
||||
sb.append("#bNo ").append(params[0].toLowerCase()).append("s found.\r\n");
|
||||
}
|
||||
sb.append("\r\n#kLoaded within ").append((double) (System.currentTimeMillis() - start) / 1000).append(" seconds.");//because I can, and it's free
|
||||
|
||||
c.getAbstractPlayerInteraction().npcTalk(NpcId.MAPLE_ADMINISTRATOR, sb.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Ronan
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class SetSlotCommand extends Command {
|
||||
{
|
||||
setDescription("Set amount of inventory slots in all tabs.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !setslot <newlevel>");
|
||||
return;
|
||||
}
|
||||
|
||||
int slots = (Integer.parseInt(params[0]) / 4) * 4;
|
||||
for (int i = 1; i < 5; i++) {
|
||||
int curSlots = player.getSlots(i);
|
||||
if (slots <= -curSlots) {
|
||||
continue;
|
||||
}
|
||||
|
||||
player.gainSlots(i, slots - curSlots, true);
|
||||
}
|
||||
|
||||
player.yellowMessage("Slots updated.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class SetStatCommand extends Command {
|
||||
{
|
||||
setDescription("Set all primary stats to new value.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !setstat <newstat>");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int x = Integer.parseInt(params[0]);
|
||||
|
||||
if (x > Short.MAX_VALUE) {
|
||||
x = Short.MAX_VALUE;
|
||||
} else if (x < 4) {
|
||||
x = 4; // thanks Vcoc for pointing the minimal allowed stat value here
|
||||
}
|
||||
|
||||
player.updateStrDexIntLuk(x);
|
||||
} catch (NumberFormatException nfe) {
|
||||
}
|
||||
}
|
||||
}
|
||||
71
src/main/java/client/command/commands/gm2/SpCommand.java
Normal file
71
src/main/java/client/command/commands/gm2/SpCommand.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class SpCommand extends Command {
|
||||
{
|
||||
setDescription("Set available SP.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !sp [<playername>] <newsp>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.length == 1) {
|
||||
int newSp = Integer.parseInt(params[0]);
|
||||
if (newSp < 0) {
|
||||
newSp = 0;
|
||||
} else if (newSp > YamlConfig.config.server.MAX_AP) {
|
||||
newSp = YamlConfig.config.server.MAX_AP;
|
||||
}
|
||||
|
||||
player.updateRemainingSp(newSp);
|
||||
} else {
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim != null) {
|
||||
int newSp = Integer.parseInt(params[1]);
|
||||
if (newSp < 0) {
|
||||
newSp = 0;
|
||||
} else if (newSp > YamlConfig.config.server.MAX_AP) {
|
||||
newSp = YamlConfig.config.server.MAX_AP;
|
||||
}
|
||||
|
||||
victim.updateRemainingSp(newSp);
|
||||
|
||||
player.dropMessage(5, "SP given.");
|
||||
} else {
|
||||
player.message("Player '" + params[0] + "' could not be found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
85
src/main/java/client/command/commands/gm2/SummonCommand.java
Normal file
85
src/main/java/client/command/commands/gm2/SummonCommand.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import net.server.Server;
|
||||
import net.server.channel.Channel;
|
||||
import server.maps.MapleMap;
|
||||
|
||||
public class SummonCommand extends Command {
|
||||
{
|
||||
setDescription("Move a player to your location.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !warphere <playername>");
|
||||
return;
|
||||
}
|
||||
|
||||
Character victim = c.getChannelServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim == null) {
|
||||
//If victim isn't on current channel, loop all channels on current world.
|
||||
|
||||
for (Channel ch : Server.getInstance().getChannelsFromWorld(c.getWorld())) {
|
||||
victim = ch.getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim != null) {
|
||||
break;//We found the person, no need to continue the loop.
|
||||
}
|
||||
}
|
||||
}
|
||||
if (victim != null) {
|
||||
if (!victim.isLoggedinWorld()) {
|
||||
player.dropMessage(6, "Player currently not logged in or unreachable.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getClient().getChannel() != victim.getClient().getChannel()) {//And then change channel if needed.
|
||||
victim.dropMessage("Changing channel, please wait a moment.");
|
||||
victim.getClient().changeChannel(player.getClient().getChannel());
|
||||
}
|
||||
|
||||
try {
|
||||
for (int i = 0; i < 7; i++) { // poll for a while until the player reconnects
|
||||
if (victim.isLoggedinWorld()) {
|
||||
break;
|
||||
}
|
||||
Thread.sleep(1777);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
MapleMap map = player.getMap();
|
||||
victim.saveLocationOnWarp();
|
||||
victim.forceChangeMap(map, map.findClosestPortal(player.getPosition()));
|
||||
} else {
|
||||
player.dropMessage(6, "Unknown player.");
|
||||
}
|
||||
}
|
||||
}
|
||||
39
src/main/java/client/command/commands/gm2/UnBugCommand.java
Normal file
39
src/main/java/client/command/commands/gm2/UnBugCommand.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import tools.PacketCreator;
|
||||
|
||||
public class UnBugCommand extends Command {
|
||||
{
|
||||
setDescription("Unbug self.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
c.getPlayer().getMap().broadcastMessage(PacketCreator.enableActions());
|
||||
}
|
||||
}
|
||||
42
src/main/java/client/command/commands/gm2/UnHideCommand.java
Normal file
42
src/main/java/client/command/commands/gm2/UnHideCommand.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
|
||||
public class UnHideCommand extends Command {
|
||||
{
|
||||
setDescription("Toggle Hide.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
SkillFactory.getSkill(9101004).getEffect(SkillFactory.getSkill(9101004).getMaxLevel()).applyTo(player);
|
||||
|
||||
}
|
||||
}
|
||||
56
src/main/java/client/command/commands/gm2/UnJailCommand.java
Normal file
56
src/main/java/client/command/commands/gm2/UnJailCommand.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class UnJailCommand extends Command {
|
||||
{
|
||||
setDescription("Free a player from jail.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !unjail <playername>");
|
||||
return;
|
||||
}
|
||||
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
if (victim != null) {
|
||||
if (victim.getJailExpirationTimeLeft() <= 0) {
|
||||
player.message("This player is already free.");
|
||||
return;
|
||||
}
|
||||
victim.removeJailExpirationTime();
|
||||
victim.message("By lack of concrete proof you are now unjailed. Enjoy freedom!");
|
||||
player.message(victim.getName() + " was unjailed.");
|
||||
} else {
|
||||
player.message("Player '" + params[0] + "' could not be found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: MedicOP - Add warparea command
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.maps.MapleMap;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Collection;
|
||||
|
||||
public class WarpAreaCommand extends Command {
|
||||
{
|
||||
setDescription("Warp all nearby players to a new map.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !warparea <mapid>");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
MapleMap target = c.getChannelServer().getMapFactory().getMap(Integer.parseInt(params[0]));
|
||||
if (target == null) {
|
||||
player.yellowMessage("Map ID " + params[0] + " is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
Point pos = player.getPosition();
|
||||
|
||||
Collection<Character> characters = player.getMap().getAllPlayers();
|
||||
|
||||
for (Character victim : characters) {
|
||||
if (victim.getPosition().distanceSq(pos) <= 50000) {
|
||||
victim.saveLocationOnWarp();
|
||||
victim.changeMap(target, target.getRandomPlayerSpawnpoint());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
player.yellowMessage("Map ID " + params[0] + " is invalid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
72
src/main/java/client/command/commands/gm2/WarpCommand.java
Normal file
72
src/main/java/client/command/commands/gm2/WarpCommand.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.maps.FieldLimit;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.MiniDungeonInfo;
|
||||
|
||||
public class WarpCommand extends Command {
|
||||
{
|
||||
setDescription("Warp to a map.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !warp <mapid>");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
MapleMap target = c.getChannelServer().getMapFactory().getMap(Integer.parseInt(params[0]));
|
||||
if (target == null) {
|
||||
player.yellowMessage("Map ID " + params[0] + " is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.isAlive()) {
|
||||
player.dropMessage(1, "This command cannot be used when you're dead.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.isGM()) {
|
||||
if (player.getEventInstance() != null || MiniDungeonInfo.isDungeonMap(player.getMapId()) || FieldLimit.CANNOTMIGRATE.check(player.getMap().getFieldLimit())) {
|
||||
player.dropMessage(1, "This command cannot be used in this map.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// expedition issue with this command detected thanks to Masterrulax
|
||||
player.saveLocationOnWarp();
|
||||
player.changeMap(target, target.getRandomPlayerSpawnpoint());
|
||||
} catch (Exception ex) {
|
||||
player.yellowMessage("Map ID " + params[0] + " is invalid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: MedicOP - Add warpmap command
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.maps.MapleMap;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class WarpMapCommand extends Command {
|
||||
{
|
||||
setDescription("Warp all characters on current map to a new map.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !warpmap <mapid>");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
MapleMap target = c.getChannelServer().getMapFactory().getMap(Integer.parseInt(params[0]));
|
||||
if (target == null) {
|
||||
player.yellowMessage("Map ID " + params[0] + " is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<Character> characters = player.getMap().getAllPlayers();
|
||||
|
||||
for (Character victim : characters) {
|
||||
victim.saveLocationOnWarp();
|
||||
victim.changeMap(target, target.getRandomPlayerSpawnpoint());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
player.yellowMessage("Map ID " + params[0] + " is invalid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm2;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.life.Monster;
|
||||
import server.life.NPC;
|
||||
import server.life.PlayerNPC;
|
||||
import server.maps.MapObject;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class WhereaMiCommand extends Command {
|
||||
{
|
||||
setDescription("Show info about objects on current map.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
HashSet<Character> chars = new HashSet<>();
|
||||
HashSet<NPC> npcs = new HashSet<>();
|
||||
HashSet<PlayerNPC> playernpcs = new HashSet<>();
|
||||
HashSet<Monster> mobs = new HashSet<>();
|
||||
|
||||
for (MapObject mmo : player.getMap().getMapObjects()) {
|
||||
if (mmo instanceof NPC npc) {
|
||||
npcs.add(npc);
|
||||
} else if (mmo instanceof Character mc) {
|
||||
chars.add(mc);
|
||||
} else if (mmo instanceof Monster mob) {
|
||||
if (mob.isAlive()) {
|
||||
mobs.add(mob);
|
||||
}
|
||||
} else if (mmo instanceof PlayerNPC npc) {
|
||||
playernpcs.add(npc);
|
||||
}
|
||||
}
|
||||
|
||||
player.yellowMessage("Map ID: " + player.getMap().getId());
|
||||
|
||||
player.yellowMessage("Players on this map:");
|
||||
for (Character chr : chars) {
|
||||
player.dropMessage(5, ">> " + chr.getName() + " - " + chr.getId() + " - Oid: " + chr.getObjectId());
|
||||
}
|
||||
|
||||
if (!playernpcs.isEmpty()) {
|
||||
player.yellowMessage("PlayerNPCs on this map:");
|
||||
for (PlayerNPC pnpc : playernpcs) {
|
||||
player.dropMessage(5, ">> " + pnpc.getName() + " - Scriptid: " + pnpc.getScriptId() + " - Oid: " + pnpc.getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
if (!npcs.isEmpty()) {
|
||||
player.yellowMessage("NPCs on this map:");
|
||||
for (NPC npc : npcs) {
|
||||
player.dropMessage(5, ">> " + npc.getName() + " - " + npc.getId() + " - Oid: " + npc.getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
if (!mobs.isEmpty()) {
|
||||
player.yellowMessage("Monsters on this map:");
|
||||
for (Monster mob : mobs) {
|
||||
if (mob.isAlive()) {
|
||||
player.dropMessage(5, ">> " + mob.getName() + " - " + mob.getId() + " - Oid: " + mob.getObjectId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
87
src/main/java/client/command/commands/gm3/BanCommand.java
Normal file
87
src/main/java/client/command/commands/gm3/BanCommand.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm3;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import net.server.Server;
|
||||
import server.TimerManager;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.PacketCreator;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class BanCommand extends Command {
|
||||
{
|
||||
setDescription("Ban a player.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 2) {
|
||||
player.yellowMessage("Syntax: !ban <IGN> <Reason> (Please be descriptive)");
|
||||
return;
|
||||
}
|
||||
String ign = params[0];
|
||||
String reason = joinStringFrom(params, 1);
|
||||
Character target = c.getChannelServer().getPlayerStorage().getCharacterByName(ign);
|
||||
if (target != null) {
|
||||
String readableTargetName = Character.makeMapleReadable(target.getName());
|
||||
String ip = target.getClient().getRemoteAddress();
|
||||
//Ban ip
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
if (ip.matches("/[0-9]{1,3}\\..*")) {
|
||||
try (PreparedStatement ps = con.prepareStatement("INSERT INTO ipbans VALUES (DEFAULT, ?, ?)")) {
|
||||
ps.setString(1, ip);
|
||||
ps.setString(2, String.valueOf(target.getClient().getAccID()));
|
||||
|
||||
ps.executeUpdate();
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
c.getPlayer().message("Error occured while banning IP address");
|
||||
c.getPlayer().message(target.getName() + "'s IP was not banned: " + ip);
|
||||
}
|
||||
target.getClient().banMacs();
|
||||
reason = c.getPlayer().getName() + " banned " + readableTargetName + " for " + reason + " (IP: " + ip + ") " + "(MAC: " + c.getMacs() + ")";
|
||||
target.ban(reason);
|
||||
target.yellowMessage("You have been banned by #b" + c.getPlayer().getName() + " #k.");
|
||||
target.yellowMessage("Reason: " + reason);
|
||||
c.sendPacket(PacketCreator.getGMEffect(4, (byte) 0));
|
||||
final Character rip = target;
|
||||
TimerManager.getInstance().schedule(() -> rip.getClient().disconnect(false, false), 5000); //5 Seconds
|
||||
Server.getInstance().broadcastMessage(c.getWorld(), PacketCreator.serverNotice(6, "[RIP]: " + ign + " has been banned."));
|
||||
} else if (Character.ban(ign, reason, false)) {
|
||||
c.sendPacket(PacketCreator.getGMEffect(4, (byte) 0));
|
||||
Server.getInstance().broadcastMessage(c.getWorld(), PacketCreator.serverNotice(6, "[RIP]: " + ign + " has been banned."));
|
||||
} else {
|
||||
c.sendPacket(PacketCreator.getGMEffect(6, (byte) 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user