@@ -223,8 +223,14 @@ public final class PacketProcessor {
|
||||
registerHandler(RecvOpcode.MONSTER_BOOK_COVER, new MonsterBookCoverHandler());
|
||||
registerHandler(RecvOpcode.AUTO_DISTRIBUTE_AP, new AutoAssignHandler());
|
||||
registerHandler(RecvOpcode.MAKER_SKILL, new MakerSkillHandler());
|
||||
registerHandler(RecvOpcode.OPEN_FAMILY_PEDIGREE, new OpenFamilyPedigreeHandler());
|
||||
registerHandler(RecvOpcode.OPEN_FAMILY, new OpenFamilyHandler());
|
||||
registerHandler(RecvOpcode.ADD_FAMILY, new FamilyAddHandler());
|
||||
registerHandler(RecvOpcode.SEPARATE_FAMILY_BY_SENIOR, new FamilySeparateHandler());
|
||||
registerHandler(RecvOpcode.SEPARATE_FAMILY_BY_JUNIOR, new FamilySeparateHandler());
|
||||
registerHandler(RecvOpcode.USE_FAMILY, new FamilyUseHandler());
|
||||
registerHandler(RecvOpcode.CHANGE_FAMILY_MESSAGE, new FamilyPreceptsHandler());
|
||||
registerHandler(RecvOpcode.FAMILY_SUMMON_RESPONSE, new FamilySummonResponseHandler());
|
||||
registerHandler(RecvOpcode.USE_HAMMER, new UseHammerHandler());
|
||||
registerHandler(RecvOpcode.SCRIPTED_ITEM, new ScriptedItemHandler());
|
||||
registerHandler(RecvOpcode.TOUCHING_REACTOR, new TouchReactorHandler());
|
||||
|
||||
@@ -145,10 +145,15 @@ public enum RecvOpcode {
|
||||
WEDDING_TALK_MORE(0x8B),
|
||||
ALLIANCE_OPERATION(0x8F),
|
||||
DENY_ALLIANCE_REQUEST(0x90),
|
||||
OPEN_FAMILY_PEDIGREE(0x91),
|
||||
OPEN_FAMILY(0x92),
|
||||
ADD_FAMILY(0x93),
|
||||
SEPARATE_FAMILY_BY_SENIOR(0x94),
|
||||
SEPARATE_FAMILY_BY_JUNIOR(0x95),
|
||||
ACCEPT_FAMILY(0x96),
|
||||
USE_FAMILY(0x97),
|
||||
CHANGE_FAMILY_MESSAGE(0x98),
|
||||
FAMILY_SUMMON_RESPONSE(0x99),
|
||||
BBS_OPERATION(0x9B),
|
||||
ENTER_MTS(0x9C),
|
||||
USE_SOLOMON_ITEM(0x9D),
|
||||
|
||||
@@ -124,7 +124,7 @@ public enum SendOpcode {
|
||||
FAMILY_JOIN_REQUEST_RESULT(0x62),
|
||||
FAMILY_JOIN_ACCEPTED(0x63),
|
||||
FAMILY_PRIVILEGE_LIST(0x64),
|
||||
FAMILY_FAMOUS_POINT_INC_RESULT(0x65),
|
||||
FAMILY_REP_GAIN(0x65),
|
||||
FAMILY_NOTIFY_LOGIN_OR_LOGOUT(0x66), //? is logged in. LOLWUT
|
||||
FAMILY_SET_PRIVILEGE(0x67),
|
||||
FAMILY_SUMMON_REQUEST(0x68),
|
||||
|
||||
@@ -80,6 +80,7 @@ import org.apache.mina.filter.codec.ProtocolCodecFilter;
|
||||
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
|
||||
|
||||
import client.MapleClient;
|
||||
import client.MapleFamily;
|
||||
import client.MapleCharacter;
|
||||
import client.SkillFactory;
|
||||
import client.command.CommandsExecutor;
|
||||
@@ -531,7 +532,7 @@ public class Server {
|
||||
return Math.max(0, nextHour.getTimeInMillis() - System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private static long getTimeLeftForNextDay() {
|
||||
public static long getTimeLeftForNextDay() {
|
||||
Calendar nextDay = Calendar.getInstance();
|
||||
nextDay.add(Calendar.DAY_OF_MONTH, 1);
|
||||
nextDay.set(Calendar.HOUR, 0);
|
||||
@@ -947,6 +948,12 @@ public class Server {
|
||||
System.out.println("[SEVERE] Syntax error in 'world.ini'.");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
if(ServerConstants.USE_FAMILY_SYSTEM) {
|
||||
timeToTake = System.currentTimeMillis();
|
||||
MapleFamily.loadAllFamilies();
|
||||
System.out.println("Families loaded in " + ((System.currentTimeMillis() - timeToTake) / 1000.0) + " seconds\r\n");
|
||||
}
|
||||
|
||||
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);
|
||||
acceptor.setHandler(new MapleServerHandler());
|
||||
|
||||
@@ -22,30 +22,132 @@
|
||||
package net.server.channel.handlers;
|
||||
|
||||
import constants.ServerConstants;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleFamily;
|
||||
import client.MapleFamilyEntry;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.coordinator.MapleInviteCoordinator;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteResult;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteType;
|
||||
import net.server.coordinator.MapleInviteCoordinator.MapleInviteResult;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.FilePrinter;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jay Estrella
|
||||
* @author Ubaware
|
||||
*/
|
||||
public final class AcceptFamilyHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if (!ServerConstants.USE_FAMILY_SYSTEM){
|
||||
return;
|
||||
}
|
||||
//System.out.println(slea.toString());
|
||||
if(!ServerConstants.USE_FAMILY_SYSTEM) {
|
||||
return;
|
||||
}
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
int inviterId = slea.readInt();
|
||||
//String inviterName = slea.readMapleAsciiString();
|
||||
slea.readMapleAsciiString();
|
||||
boolean accept = slea.readByte() != 0;
|
||||
// String inviterName = slea.readMapleAsciiString();
|
||||
MapleCharacter inviter = c.getWorldServer().getPlayerStorage().getCharacterById(inviterId);
|
||||
if (inviter != null) {
|
||||
inviter.getClient().announce(MaplePacketCreator.sendFamilyJoinResponse(true, c.getPlayer().getName()));
|
||||
if(inviter != null) {
|
||||
MapleInviteResult inviteResult = MapleInviteCoordinator.answerInvite(InviteType.FAMILY, c.getPlayer().getId(), c.getPlayer(), accept);
|
||||
if(inviteResult.result == InviteResult.NOT_FOUND) return; //was never invited. (or expired on server only somehow?)
|
||||
if(accept) {
|
||||
if(inviter.getFamily() != null) {
|
||||
if(chr.getFamily() == null) {
|
||||
MapleFamilyEntry newEntry = new MapleFamilyEntry(inviter.getFamily(), chr.getId(), chr.getName(), chr.getLevel(), chr.getJob());
|
||||
newEntry.setCharacter(chr);
|
||||
if(!newEntry.setSenior(inviter.getFamilyEntry(), true)) {
|
||||
inviter.announce(MaplePacketCreator.sendFamilyMessage(1, 0));
|
||||
return;
|
||||
} else {
|
||||
// save
|
||||
inviter.getFamily().addEntry(newEntry);
|
||||
insertNewFamilyRecord(chr.getId(), inviter.getFamily().getID(), inviter.getId(), false);
|
||||
}
|
||||
} else { //absorb target family
|
||||
MapleFamilyEntry targetEntry = chr.getFamilyEntry();
|
||||
MapleFamily targetFamily = targetEntry.getFamily();
|
||||
if(targetFamily.getLeader() != targetEntry) return;
|
||||
if(inviter.getFamily().getTotalGenerations() + targetFamily.getTotalGenerations() <= ServerConstants.FAMILY_MAX_GENERATIONS) {
|
||||
targetEntry.join(inviter.getFamilyEntry());
|
||||
} else {
|
||||
inviter.announce(MaplePacketCreator.sendFamilyMessage(76, 0));
|
||||
chr.announce(MaplePacketCreator.sendFamilyMessage(76, 0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else { // create new family
|
||||
if(chr.getFamily() != null && inviter.getFamily() != null && chr.getFamily().getTotalGenerations() + inviter.getFamily().getTotalGenerations() >= ServerConstants.FAMILY_MAX_GENERATIONS) {
|
||||
inviter.announce(MaplePacketCreator.sendFamilyMessage(76, 0));
|
||||
chr.announce(MaplePacketCreator.sendFamilyMessage(76, 0));
|
||||
return;
|
||||
}
|
||||
MapleFamily newFamily = new MapleFamily(-1, c.getWorld());
|
||||
c.getWorldServer().addFamily(newFamily.getID(), newFamily);
|
||||
MapleFamilyEntry inviterEntry = new MapleFamilyEntry(newFamily, inviter.getId(), inviter.getName(), inviter.getLevel(), inviter.getJob());
|
||||
inviterEntry.setCharacter(inviter);
|
||||
newFamily.setLeader(inviter.getFamilyEntry());
|
||||
newFamily.addEntry(inviterEntry);
|
||||
if(chr.getFamily() == null) { //completely new family
|
||||
MapleFamilyEntry newEntry = new MapleFamilyEntry(newFamily, chr.getId(), chr.getName(), chr.getLevel(), chr.getJob());
|
||||
newEntry.setCharacter(chr);
|
||||
newEntry.setSenior(inviterEntry, true);
|
||||
// save new family
|
||||
insertNewFamilyRecord(inviter.getId(), newFamily.getID(), 0, true);
|
||||
insertNewFamilyRecord(chr.getId(), newFamily.getID(), inviter.getId(), false); // char was already saved by setSenior() above
|
||||
newFamily.setMessage("", true);
|
||||
} else { //new family for inviter, absorb invitee family
|
||||
insertNewFamilyRecord(inviter.getId(), newFamily.getID(), 0 , true);
|
||||
newFamily.setMessage("", true);
|
||||
chr.getFamilyEntry().join(inviterEntry);
|
||||
}
|
||||
}
|
||||
c.getPlayer().getFamily().broadcast(MaplePacketCreator.sendFamilyJoinResponse(true, c.getPlayer().getName()), c.getPlayer().getId());
|
||||
c.announce(MaplePacketCreator.getSeniorMessage(inviter.getName()));
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(chr.getFamilyEntry()));
|
||||
chr.getFamilyEntry().updateSeniorFamilyInfo(true);
|
||||
} else {
|
||||
inviter.announce(MaplePacketCreator.sendFamilyJoinResponse(false, c.getPlayer().getName()));
|
||||
}
|
||||
}
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(0, 0));
|
||||
}
|
||||
|
||||
private static void insertNewFamilyRecord(int characterID, int familyID, int seniorID, boolean updateChar) {
|
||||
try(Connection con = DatabaseConnection.getConnection()) {
|
||||
try(PreparedStatement ps = con.prepareStatement("INSERT INTO family_character (cid, familyid, seniorid) VALUES (?, ?, ?)")) {
|
||||
ps.setInt(1, characterID);
|
||||
ps.setInt(2, familyID);
|
||||
ps.setInt(3, seniorID);
|
||||
ps.executeUpdate();
|
||||
} catch(SQLException e) {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not save new family record for char id " + characterID + ".");
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(updateChar) {
|
||||
try(PreparedStatement ps = con.prepareStatement("UPDATE characters SET familyid = ? WHERE id = ?")) {
|
||||
ps.setInt(1, familyID);
|
||||
ps.setInt(2, characterID);
|
||||
ps.executeUpdate();
|
||||
} catch(SQLException e) {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not update 'characters' 'familyid' record for char id " + characterID + ".");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch(SQLException e) {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not get connection to DB.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public final class DenyPartyRequestHandler extends AbstractMaplePacketHandler {
|
||||
if (cfrom != null) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
|
||||
if (MapleInviteCoordinator.answerInvite(InviteType.PARTY, chr.getId(), cfrom.getPartyId(), false).getLeft() == InviteResult.DENIED) {
|
||||
if (MapleInviteCoordinator.answerInvite(InviteType.PARTY, chr.getId(), cfrom.getPartyId(), false).result == InviteResult.DENIED) {
|
||||
chr.updatePartySearchAvailability(chr.getParty() == null);
|
||||
cfrom.getClient().announce(MaplePacketCreator.partyStatusMessage(23, chr.getName()));
|
||||
}
|
||||
|
||||
@@ -25,29 +25,44 @@ import constants.ServerConstants;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.coordinator.MapleInviteCoordinator;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteType;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jay Estrella
|
||||
* @author Ubaware
|
||||
*/
|
||||
public final class FamilyAddHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if (!ServerConstants.USE_FAMILY_SYSTEM){
|
||||
return;
|
||||
}
|
||||
System.out.println(slea.toString());
|
||||
if(!ServerConstants.USE_FAMILY_SYSTEM) {
|
||||
return;
|
||||
}
|
||||
String toAdd = slea.readMapleAsciiString();
|
||||
MapleCharacter addChr = c.getChannelServer().getPlayerStorage().getCharacterByName(toAdd);
|
||||
if (addChr != null) {
|
||||
addChr.getClient().announce(MaplePacketCreator.sendFamilyInvite(c.getPlayer().getId(), toAdd));
|
||||
c.getPlayer().dropMessage("The invite has been sent.");
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
if(addChr == null) {
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(65, 0));
|
||||
} else if(addChr.getMap() != chr.getMap() || (addChr.isHidden()) && chr.gmLevel() < addChr.gmLevel()) {
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(69, 0));
|
||||
} else if(addChr.getLevel() <= 10) {
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(77, 0));
|
||||
} else if(Math.abs(addChr.getLevel() - chr.getLevel()) > 20) {
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(72, 0));
|
||||
} else if(addChr.getFamily() != null && addChr.getFamily() == chr.getFamily()) { //same family
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
} else if(MapleInviteCoordinator.hasInvite(InviteType.FAMILY, addChr.getId())) {
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(73, 0));
|
||||
} else if(chr.getFamily() != null && addChr.getFamily() != null && addChr.getFamily().getTotalGenerations() + chr.getFamily().getTotalGenerations() > ServerConstants.FAMILY_MAX_GENERATIONS) {
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(76, 0));
|
||||
} else {
|
||||
c.getPlayer().dropMessage("The player cannot be found!");
|
||||
MapleInviteCoordinator.createInvite(InviteType.FAMILY, chr, addChr, addChr.getId());
|
||||
addChr.getClient().announce(MaplePacketCreator.sendFamilyInvite(chr.getId(), chr.getName()));
|
||||
chr.dropMessage("The invite has been sent.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
23
src/net/server/channel/handlers/FamilyPreceptsHandler.java
Normal file
23
src/net/server/channel/handlers/FamilyPreceptsHandler.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package net.server.channel.handlers;
|
||||
|
||||
import client.MapleClient;
|
||||
import client.MapleFamily;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
public class FamilyPreceptsHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@Override
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MapleFamily family = c.getPlayer().getFamily();
|
||||
if(family == null) return;
|
||||
if(family.getLeader().getChr() != c.getPlayer()) return; //only the leader can set the precepts
|
||||
String newPrecepts = slea.readMapleAsciiString();
|
||||
if(newPrecepts.length() > 200) return;
|
||||
family.setMessage(newPrecepts, true);
|
||||
//family.broadcastFamilyInfoUpdate(); //probably don't need to broadcast for this?
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(c.getPlayer().getFamilyEntry()));
|
||||
}
|
||||
|
||||
}
|
||||
78
src/net/server/channel/handlers/FamilySeparateHandler.java
Normal file
78
src/net/server/channel/handlers/FamilySeparateHandler.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2018 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 net.server.channel.handlers;
|
||||
|
||||
import client.MapleClient;
|
||||
import client.MapleFamily;
|
||||
import client.MapleFamilyEntry;
|
||||
import constants.ServerConstants;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
public class FamilySeparateHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@Override
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if(!ServerConstants.USE_FAMILY_SYSTEM) return;
|
||||
MapleFamily oldFamily = c.getPlayer().getFamily();
|
||||
if(oldFamily == null) return;
|
||||
MapleFamilyEntry forkOn = null;
|
||||
boolean isSenior;
|
||||
if(slea.available() > 0) { //packet 0x95 doesn't send id, since there is only one senior
|
||||
forkOn = c.getPlayer().getFamily().getEntryByID(slea.readInt());
|
||||
if(!c.getPlayer().getFamilyEntry().isJunior(forkOn)) return; //packet editing?
|
||||
isSenior = true;
|
||||
} else {
|
||||
forkOn = c.getPlayer().getFamilyEntry();
|
||||
isSenior = false;
|
||||
}
|
||||
if(forkOn == null) return;
|
||||
|
||||
MapleFamilyEntry senior = forkOn.getSenior();
|
||||
if(senior == null) return;
|
||||
int levelDiff = Math.abs(c.getPlayer().getLevel() - senior.getLevel());
|
||||
int cost = 2500 * levelDiff;
|
||||
cost += levelDiff * levelDiff;
|
||||
if(c.getPlayer().getMeso() < cost) {
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(isSenior ? 81 : 80, cost));
|
||||
return;
|
||||
}
|
||||
c.getPlayer().gainMeso(-cost);
|
||||
int repCost = separateRepCost(forkOn);
|
||||
senior.gainReputation(-repCost, false);
|
||||
if(senior.getSenior() != null) senior.getSenior().gainReputation(-(repCost/2), false);
|
||||
forkOn.announceToSenior(MaplePacketCreator.serverNotice(5, forkOn.getName() + " has left the family."), true);
|
||||
forkOn.fork();
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(forkOn)); //pedigree info will be requested by the client if the window is open
|
||||
forkOn.updateSeniorFamilyInfo(true);
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(1, 0));
|
||||
}
|
||||
|
||||
|
||||
private static int separateRepCost(MapleFamilyEntry junior) {
|
||||
int level = junior.getLevel();
|
||||
int ret = level / 20;
|
||||
ret += 10;
|
||||
ret *= level;
|
||||
ret *= 2;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package net.server.channel.handlers;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleFamilyEntitlement;
|
||||
import client.MapleFamilyEntry;
|
||||
import constants.ServerConstants;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.coordinator.MapleInviteCoordinator;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteResult;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteType;
|
||||
import net.server.coordinator.MapleInviteCoordinator.MapleInviteResult;
|
||||
import server.maps.MapleMap;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
public class FamilySummonResponseHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@Override
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if(!ServerConstants.USE_FAMILY_SYSTEM) return;
|
||||
slea.readMapleAsciiString(); //family name
|
||||
boolean accept = slea.readByte() != 0;
|
||||
MapleInviteResult inviteResult = MapleInviteCoordinator.answerInvite(InviteType.FAMILY_SUMMON, c.getPlayer().getId(), c.getPlayer(), accept);
|
||||
if(inviteResult.result == InviteResult.NOT_FOUND) return;
|
||||
MapleCharacter inviter = inviteResult.from;
|
||||
MapleFamilyEntry inviterEntry = inviter.getFamilyEntry();
|
||||
if(inviterEntry == null) return;
|
||||
MapleMap map = (MapleMap) inviteResult.params[0];
|
||||
if(accept && inviter.getMap() == map) { //cancel if inviter has changed maps
|
||||
c.getPlayer().changeMap(map, map.getPortal(0));
|
||||
} else {
|
||||
inviterEntry.refundEntitlement(MapleFamilyEntitlement.SUMMON_FAMILY);
|
||||
inviterEntry.gainReputation(MapleFamilyEntitlement.SUMMON_FAMILY.getRepCost(), false); //refund rep cost if declined
|
||||
inviter.announce(MaplePacketCreator.getFamilyInfo(inviterEntry));
|
||||
inviter.dropMessage(5, c.getPlayer().getName() + " has denied the summon request.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,82 +21,121 @@
|
||||
*/
|
||||
package net.server.channel.handlers;
|
||||
|
||||
import constants.ServerConstants;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleFamilyEntitlement;
|
||||
import client.MapleFamilyEntry;
|
||||
import constants.ServerConstants;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.opcodes.SendOpcode;
|
||||
import net.server.coordinator.MapleInviteCoordinator;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteType;
|
||||
import server.maps.FieldLimit;
|
||||
import server.maps.MapleMap;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import tools.data.output.MaplePacketLittleEndianWriter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Moogra
|
||||
* @author Ubaware
|
||||
*/
|
||||
public final class FamilyUseHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if (!ServerConstants.USE_FAMILY_SYSTEM){
|
||||
return;
|
||||
}
|
||||
int[] repCost = {3, 5, 7, 8, 10, 12, 15, 20, 25, 40, 50};
|
||||
final int type = slea.readInt();
|
||||
if(!ServerConstants.USE_FAMILY_SYSTEM) {
|
||||
return;
|
||||
}
|
||||
MapleFamilyEntitlement type = MapleFamilyEntitlement.values()[slea.readInt()];
|
||||
int cost = type.getRepCost();
|
||||
MapleFamilyEntry entry = c.getPlayer().getFamilyEntry();
|
||||
if(entry.getReputation() < cost || entry.isEntitlementUsed(type)) {
|
||||
return; // shouldn't even be able to request it
|
||||
}
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(entry));
|
||||
MapleCharacter victim;
|
||||
if (type == 0 || type == 1) {
|
||||
if(type == MapleFamilyEntitlement.FAMILY_REUINION || type == MapleFamilyEntitlement.SUMMON_FAMILY) {
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(slea.readMapleAsciiString());
|
||||
if (victim != null) {
|
||||
if (type == 0) {
|
||||
c.getPlayer().changeMap(victim.getMap(), victim.getMap().getPortal(0));
|
||||
if(victim != null && victim != c.getPlayer()) {
|
||||
if(victim.getFamily() == c.getPlayer().getFamily()) {
|
||||
MapleMap targetMap = victim.getMap();
|
||||
MapleMap ownMap = c.getPlayer().getMap();
|
||||
if(targetMap != null) {
|
||||
if(type == MapleFamilyEntitlement.FAMILY_REUINION) {
|
||||
if(!FieldLimit.CANNOTMIGRATE.check(ownMap.getFieldLimit()) && !FieldLimit.CANNOTVIPROCK.check(targetMap.getFieldLimit())
|
||||
&& (targetMap.getForcedReturnId() == 999999999 || targetMap.getId() < 100000000) && targetMap.getEventInstance() == null) {
|
||||
|
||||
c.getPlayer().changeMap(victim.getMap(), victim.getMap().getPortal(0));
|
||||
useEntitlement(entry, type);
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(75, 0)); // wrong message, but close enough. (client should check this first anyway)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(!FieldLimit.CANNOTMIGRATE.check(targetMap.getFieldLimit()) && !FieldLimit.CANNOTVIPROCK.check(ownMap.getFieldLimit())
|
||||
&& (ownMap.getForcedReturnId() == 999999999 || ownMap.getId() < 100000000) && ownMap.getEventInstance() == null) {
|
||||
|
||||
if(MapleInviteCoordinator.hasInvite(InviteType.FAMILY_SUMMON, victim.getId())) {
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(74, 0));
|
||||
return;
|
||||
}
|
||||
MapleInviteCoordinator.createInvite(InviteType.FAMILY_SUMMON, c.getPlayer(), victim, victim.getId(), c.getPlayer().getMap());
|
||||
victim.announce(MaplePacketCreator.sendFamilySummonRequest(c.getPlayer().getFamily().getName(), c.getPlayer().getName()));
|
||||
useEntitlement(entry, type);
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(75, 0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
victim.changeMap(c.getPlayer().getMap(), c.getPlayer().getMap().getPortal(0));
|
||||
c.announce(MaplePacketCreator.sendFamilyMessage(67, 0));
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if(type == MapleFamilyEntitlement.FAMILY_BONDING) {
|
||||
//not implemented
|
||||
} else {
|
||||
int erate = type == 3 ? 150 : (type == 4 || type == 6 || type == 8 || type == 10 ? 200 : 100);
|
||||
int drate = type == 2 ? 150 : (type == 4 || type == 5 || type == 7 || type == 9 ? 200 : 100);
|
||||
if (type > 8) {
|
||||
} else {
|
||||
c.announce(useRep(drate == 100 ? 2 : (erate == 100 ? 3 : 4), type, erate, drate, ((type > 5 || type == 4) ? 2 : 1) * 15 * 60 * 1000));
|
||||
}
|
||||
boolean party = false;
|
||||
boolean isExp = false;
|
||||
float rate = 1.5f;
|
||||
int duration = 15;
|
||||
do {
|
||||
switch(type) {
|
||||
case PARTY_EXP_2_30MIN:
|
||||
party = true;
|
||||
isExp = true;
|
||||
type = MapleFamilyEntitlement.SELF_EXP_2_30MIN;
|
||||
continue;
|
||||
case PARTY_DROP_2_30MIN:
|
||||
party = true;
|
||||
type = MapleFamilyEntitlement.SELF_DROP_2_30MIN;
|
||||
continue;
|
||||
case SELF_DROP_2_30MIN:
|
||||
duration = 30;
|
||||
case SELF_DROP_2:
|
||||
rate = 2.0f;
|
||||
case SELF_DROP_1_5:
|
||||
break;
|
||||
case SELF_EXP_2_30MIN:
|
||||
duration = 30;
|
||||
case SELF_EXP_2:
|
||||
rate = 2.0f;
|
||||
case SELF_EXP_1_5:
|
||||
isExp = true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} while(true);
|
||||
//not implemented
|
||||
}
|
||||
c.getPlayer().getFamily().getMember(c.getPlayer().getId()).gainReputation(repCost[type]);
|
||||
}
|
||||
|
||||
/**
|
||||
* [65 00][02][08 00 00 00][C8 00 00 00][00 00 00 00][00][40 77 1B 00]
|
||||
*/
|
||||
private static byte[] useRep(int mode, int type, int erate, int drate, int time) {
|
||||
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(0x60);//noty
|
||||
mplew.write(mode);
|
||||
mplew.writeInt(type);
|
||||
if (mode < 4) {
|
||||
mplew.writeInt(erate);
|
||||
mplew.writeInt(drate);
|
||||
|
||||
private boolean useEntitlement(MapleFamilyEntry entry, MapleFamilyEntitlement entitlement) {
|
||||
if(entry.useEntitlement(entitlement)) {
|
||||
entry.gainReputation(-entitlement.getRepCost(), false);
|
||||
entry.getChr().announce(MaplePacketCreator.getFamilyInfo(entry));
|
||||
return true;
|
||||
}
|
||||
mplew.write(0);
|
||||
mplew.writeInt(time);
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
//20 00
|
||||
//00 00 00 00
|
||||
//00 00 00 00 00 00 00 00
|
||||
//80 01
|
||||
//00 00 28 00
|
||||
//8C 93 3E 00
|
||||
//40 0D
|
||||
//03 00 14 00
|
||||
//8C 93 3E 00
|
||||
//40 0D 03 00 00 00 00 00 02
|
||||
private static byte[] giveBuff() {
|
||||
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.GIVE_BUFF.getValue());
|
||||
mplew.writeInt(0);
|
||||
mplew.writeLong(0);
|
||||
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ import net.AbstractMaplePacketHandler;
|
||||
import net.server.coordinator.MapleInviteCoordinator;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteResult;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteType;
|
||||
import net.server.coordinator.MapleInviteCoordinator.MapleInviteResult;
|
||||
import net.server.world.MapleMessenger;
|
||||
import net.server.world.MapleMessengerCharacter;
|
||||
import net.server.world.World;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
public final class MessengerHandler extends AbstractMaplePacketHandler {
|
||||
@@ -58,8 +58,8 @@ public final class MessengerHandler extends AbstractMaplePacketHandler {
|
||||
} else {
|
||||
messenger = world.getMessenger(messengerid);
|
||||
if (messenger != null) {
|
||||
Pair<InviteResult, MapleCharacter> inviteRes = MapleInviteCoordinator.answerInvite(InviteType.MESSENGER, player.getId(), messengerid, true);
|
||||
InviteResult res = inviteRes.getLeft();
|
||||
MapleInviteResult inviteRes = MapleInviteCoordinator.answerInvite(InviteType.MESSENGER, player.getId(), messengerid, true);
|
||||
InviteResult res = inviteRes.result;
|
||||
if (res == InviteResult.ACCEPTED) {
|
||||
int position = messenger.getLowestPosition();
|
||||
MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, position);
|
||||
|
||||
41
src/net/server/channel/handlers/OpenFamilyHandler.java
Normal file
41
src/net/server/channel/handlers/OpenFamilyHandler.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2018 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 net.server.channel.handlers;
|
||||
|
||||
import constants.ServerConstants;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ubaware
|
||||
*/
|
||||
public final class OpenFamilyHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if(!ServerConstants.USE_FAMILY_SYSTEM) return;
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(chr.getFamilyEntry()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2018 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 net.server.channel.handlers;
|
||||
|
||||
import constants.ServerConstants;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ubaware
|
||||
*/
|
||||
public final class OpenFamilyPedigreeHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if(!ServerConstants.USE_FAMILY_SYSTEM) return;
|
||||
MapleCharacter target = c.getChannelServer().getPlayerStorage().getCharacterByName(slea.readMapleAsciiString());
|
||||
if(target != null && target.getFamily() != null) {
|
||||
c.announce(MaplePacketCreator.showPedigree(target.getFamilyEntry()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import constants.ServerConstants;
|
||||
import net.server.coordinator.MapleInviteCoordinator;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteResult;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteType;
|
||||
import tools.Pair;
|
||||
import net.server.coordinator.MapleInviteCoordinator.MapleInviteResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -64,8 +64,8 @@ public final class PartyOperationHandler extends AbstractMaplePacketHandler {
|
||||
case 3: { // join
|
||||
int partyid = slea.readInt();
|
||||
|
||||
Pair<InviteResult, MapleCharacter> inviteRes = MapleInviteCoordinator.answerInvite(InviteType.PARTY, player.getId(), partyid, true);
|
||||
InviteResult res = inviteRes.getLeft();
|
||||
MapleInviteResult inviteRes = MapleInviteCoordinator.answerInvite(InviteType.PARTY, player.getId(), partyid, true);
|
||||
InviteResult res = inviteRes.result;
|
||||
if (res == InviteResult.ACCEPTED) {
|
||||
MapleParty.joinParty(player, partyid, false);
|
||||
} else {
|
||||
|
||||
@@ -40,6 +40,7 @@ import net.server.world.MaplePartyCharacter;
|
||||
import net.server.world.PartyOperation;
|
||||
import net.server.world.World;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.FilePrinter;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
@@ -50,6 +51,7 @@ import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleDisease;
|
||||
import client.MapleFamily;
|
||||
import client.MapleFamilyEntry;
|
||||
import client.MapleKeyBinding;
|
||||
import client.SkillFactory;
|
||||
import client.inventory.Equip;
|
||||
@@ -260,12 +262,22 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
c.announce(MaplePacketCreator.loadFamily(player));
|
||||
if (player.getFamilyId() > 0) {
|
||||
MapleFamily f = wserv.getFamily(player.getFamilyId());
|
||||
if (f == null) {
|
||||
f = new MapleFamily(player.getId());
|
||||
wserv.addFamily(player.getFamilyId(), f);
|
||||
if(f != null) {
|
||||
MapleFamilyEntry familyEntry = f.getEntryByID(player.getId());
|
||||
if(familyEntry != null) {
|
||||
familyEntry.setCharacter(player);
|
||||
player.setFamilyEntry(familyEntry);
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, "Player " + player.getName() + "'s family doesn't have an entry for them. (" + f.getID() + ")");
|
||||
}
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(familyEntry));
|
||||
familyEntry.announceToSenior(MaplePacketCreator.sendFamilyLoginNotice(player.getName(), true), true);
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, "Player " + player.getName() + " has an invalid family ID. (" + player.getFamilyId() + ")");
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(null));
|
||||
}
|
||||
player.setFamily(f);
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(f.getMember(player.getId())));
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.getFamilyInfo(null));
|
||||
}
|
||||
if (player.getGuildId() > 0) {
|
||||
MapleGuild playerGuild = server.getGuild(player.getGuildId(), player.getWorld(), player);
|
||||
@@ -410,6 +422,10 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
if (ServerConstants.USE_NPCS_SCRIPTABLE) {
|
||||
c.announce(MaplePacketCreator.setNPCScriptable(ScriptableNPCConstants.SCRIPTABLE_NPCS));
|
||||
}
|
||||
|
||||
if(newcomer) player.setLoginTime(System.currentTimeMillis());
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
c.releaseClient();
|
||||
}
|
||||
|
||||
@@ -427,17 +427,9 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
slea.readByte();
|
||||
slea.readInt();
|
||||
if(itemId == 5400000) { //name change
|
||||
if(player.cancelPendingNameChange()) {
|
||||
player.dropMessage(1, "Successfully canceled pending name change.");
|
||||
} else {
|
||||
player.dropMessage(1, "You do not have a pending name change.");
|
||||
}
|
||||
c.announce(MaplePacketCreator.showNameChangeCancel(player.cancelPendingNameChange()));
|
||||
} else if(itemId == 5401000) { //world transfer
|
||||
if(player.cancelPendingWorldTranfer()) {
|
||||
player.dropMessage(1, "Successfully canceled pending world transfer.");
|
||||
} else {
|
||||
player.dropMessage(1, "You do not have a pending world transfer.");
|
||||
}
|
||||
c.announce(MaplePacketCreator.showWorldTransferCancel(player.cancelPendingWorldTranfer()));
|
||||
}
|
||||
remove(c, position, itemId);
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
|
||||
@@ -42,7 +42,8 @@ public class MapleInviteCoordinator {
|
||||
|
||||
public enum InviteType {
|
||||
//BUDDY, (not needed)
|
||||
//FAMILY, (not implemented)
|
||||
FAMILY,
|
||||
FAMILY_SUMMON,
|
||||
MESSENGER,
|
||||
TRADE,
|
||||
PARTY,
|
||||
@@ -52,11 +53,13 @@ public class MapleInviteCoordinator {
|
||||
final ConcurrentHashMap<Integer, Object> invites;
|
||||
final ConcurrentHashMap<Integer, MapleCharacter> inviteFrom;
|
||||
final ConcurrentHashMap<Integer, Integer> inviteTimeouts;
|
||||
final ConcurrentHashMap<Integer, Object[]> inviteParams;
|
||||
|
||||
private InviteType() {
|
||||
invites = new ConcurrentHashMap<>();
|
||||
inviteTimeouts = new ConcurrentHashMap<>();
|
||||
inviteFrom = new ConcurrentHashMap<>();
|
||||
inviteParams = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
private Map<Integer, Object> getRequestsTable() {
|
||||
@@ -67,15 +70,15 @@ public class MapleInviteCoordinator {
|
||||
return inviteTimeouts;
|
||||
}
|
||||
|
||||
private MapleCharacter removeRequest(Integer target) {
|
||||
private Pair<MapleCharacter, Object[]> removeRequest(Integer target) {
|
||||
invites.remove(target);
|
||||
MapleCharacter from = inviteFrom.remove(target);
|
||||
inviteTimeouts.remove(target);
|
||||
|
||||
return from;
|
||||
return new Pair<>(from, inviteParams.remove(target));
|
||||
}
|
||||
|
||||
private boolean addRequest(MapleCharacter from, Object referenceFrom, int targetCid) {
|
||||
private boolean addRequest(MapleCharacter from, Object referenceFrom, int targetCid, Object[] params) {
|
||||
Object v = invites.putIfAbsent(targetCid, referenceFrom);
|
||||
if (v != null) { // there was already an entry
|
||||
return false;
|
||||
@@ -83,7 +86,7 @@ public class MapleInviteCoordinator {
|
||||
|
||||
inviteFrom.put(targetCid, from);
|
||||
inviteTimeouts.put(targetCid, 0);
|
||||
|
||||
inviteParams.put(targetCid, params);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -93,29 +96,31 @@ public class MapleInviteCoordinator {
|
||||
}
|
||||
|
||||
// note: referenceFrom is a specific value that represents the "common association" created between the sender/recver parties
|
||||
public static boolean createInvite(InviteType type, MapleCharacter from, Object referenceFrom, int targetCid) {
|
||||
return type.addRequest(from, referenceFrom, targetCid);
|
||||
public static boolean createInvite(InviteType type, MapleCharacter from, Object referenceFrom, int targetCid, Object... params) {
|
||||
return type.addRequest(from, referenceFrom, targetCid, params);
|
||||
}
|
||||
|
||||
public static boolean hasInvite(InviteType type, int targetCid) {
|
||||
return type.hasRequest(targetCid);
|
||||
}
|
||||
|
||||
public static Pair<InviteResult, MapleCharacter> answerInvite(InviteType type, int targetCid, Object referenceFrom, boolean answer) {
|
||||
public static MapleInviteResult answerInvite(InviteType type, int targetCid, Object referenceFrom, boolean answer) {
|
||||
Map<Integer, Object> table = type.getRequestsTable();
|
||||
|
||||
MapleCharacter from = null;
|
||||
InviteResult result = InviteResult.NOT_FOUND;
|
||||
Pair<MapleCharacter, Object[]> inviteInfo = null;
|
||||
|
||||
Object reference = table.get(targetCid);
|
||||
if (referenceFrom.equals(reference)) {
|
||||
from = type.removeRequest(targetCid);
|
||||
inviteInfo = type.removeRequest(targetCid);
|
||||
from = inviteInfo.getLeft();
|
||||
if (from != null && !from.isLoggedinWorld()) from = null;
|
||||
|
||||
result = answer ? InviteResult.ACCEPTED : InviteResult.DENIED;
|
||||
}
|
||||
|
||||
return new Pair<>(result, from);
|
||||
return new MapleInviteResult(result, from, inviteInfo != null ? inviteInfo.getRight() : new Object[0]);
|
||||
}
|
||||
|
||||
public static void removeInvite(InviteType type, int targetCid) {
|
||||
@@ -146,4 +151,17 @@ public class MapleInviteCoordinator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MapleInviteResult {
|
||||
|
||||
public final InviteResult result;
|
||||
public final MapleCharacter from;
|
||||
public final Object[] params;
|
||||
|
||||
private MapleInviteResult(InviteResult result, MapleCharacter from, Object[] params) {
|
||||
this.result = result;
|
||||
this.from = from;
|
||||
this.params = params;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,13 +32,12 @@ import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import net.server.Server;
|
||||
import net.server.coordinator.MapleInviteCoordinator;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteResult;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteType;
|
||||
import net.server.coordinator.MapleInviteCoordinator.MapleInviteResult;
|
||||
import net.server.world.MapleParty;
|
||||
import net.server.world.MaplePartyCharacter;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -494,11 +493,11 @@ public class MapleAlliance {
|
||||
}
|
||||
|
||||
public static boolean answerInvitation(int targetId, String targetGuildName, int allianceId, boolean answer) {
|
||||
Pair<InviteResult, MapleCharacter> res = MapleInviteCoordinator.answerInvite(InviteType.ALLIANCE, targetId, allianceId, answer);
|
||||
MapleInviteResult res = MapleInviteCoordinator.answerInvite(InviteType.ALLIANCE, targetId, allianceId, answer);
|
||||
|
||||
String msg;
|
||||
MapleCharacter sender = res.getRight();
|
||||
switch (res.getLeft()) {
|
||||
MapleCharacter sender = res.from;
|
||||
switch (res.result) {
|
||||
case ACCEPTED:
|
||||
return true;
|
||||
|
||||
|
||||
@@ -45,11 +45,10 @@ import net.server.Server;
|
||||
import net.server.channel.Channel;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.coordinator.MapleInviteCoordinator;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteType;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteResult;
|
||||
import net.server.coordinator.MapleInviteCoordinator.MapleInviteResult;
|
||||
import net.server.coordinator.MapleMatchCheckerCoordinator;
|
||||
|
||||
public class MapleGuild {
|
||||
@@ -727,11 +726,11 @@ public class MapleGuild {
|
||||
}
|
||||
|
||||
public static boolean answerInvitation(int targetId, String targetName, int guildId, boolean answer) {
|
||||
Pair<InviteResult, MapleCharacter> res = MapleInviteCoordinator.answerInvite(InviteType.GUILD, targetId, guildId, answer);
|
||||
MapleInviteResult res = MapleInviteCoordinator.answerInvite(InviteType.GUILD, targetId, guildId, answer);
|
||||
|
||||
MapleGuildResponse mgr;
|
||||
MapleCharacter sender = res.getRight();
|
||||
switch (res.getLeft()) {
|
||||
MapleCharacter sender = res.from;
|
||||
switch (res.result) {
|
||||
case ACCEPTED:
|
||||
return true;
|
||||
|
||||
|
||||
56
src/net/server/worker/FamilyDailyResetWorker.java
Normal file
56
src/net/server/worker/FamilyDailyResetWorker.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package net.server.worker;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Calendar;
|
||||
|
||||
import client.MapleFamily;
|
||||
import net.server.world.World;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.FilePrinter;
|
||||
|
||||
public class FamilyDailyResetWorker implements Runnable {
|
||||
|
||||
private final World world;
|
||||
|
||||
public FamilyDailyResetWorker(World world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
resetEntitlementUsage(world);
|
||||
for(MapleFamily family : world.getFamilies()) {
|
||||
family.resetDailyReps();
|
||||
}
|
||||
}
|
||||
|
||||
public static void resetEntitlementUsage(World world) {
|
||||
Calendar resetTime = Calendar.getInstance();
|
||||
resetTime.add(Calendar.MINUTE, 1); // to make sure that we're in the "next day", since this is called at midnight
|
||||
resetTime.set(Calendar.HOUR, 0);
|
||||
resetTime.set(Calendar.MINUTE, 0);
|
||||
resetTime.set(Calendar.SECOND, 0);
|
||||
resetTime.set(Calendar.MILLISECOND, 0);
|
||||
try(Connection con = DatabaseConnection.getConnection()) {
|
||||
try(PreparedStatement ps = con.prepareStatement("UPDATE family_character SET todaysrep = 0, reptosenior = 0 WHERE lastresettime <= ?")) {
|
||||
ps.setLong(1, resetTime.getTimeInMillis());
|
||||
ps.executeUpdate();
|
||||
} catch(SQLException e) {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not reset daily rep for families. On " + Calendar.getInstance().getTime());
|
||||
e.printStackTrace();
|
||||
}
|
||||
try(PreparedStatement ps = con.prepareStatement("DELETE FROM family_entitlement WHERE timestamp <= ?")) {
|
||||
ps.setLong(1, resetTime.getTimeInMillis());
|
||||
ps.executeUpdate();
|
||||
} catch(SQLException e) {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not do daily reset for family entitlements. On " + Calendar.getInstance().getTime());
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch(SQLException e) {
|
||||
FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not get connection to DB.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@ import server.maps.MaplePlayerShop;
|
||||
import server.maps.MaplePlayerShopItem;
|
||||
import server.maps.AbstractMapleMapObject;
|
||||
import net.server.worker.CharacterAutosaverWorker;
|
||||
import net.server.worker.FamilyDailyResetWorker;
|
||||
import net.server.worker.FishingWorker;
|
||||
import net.server.worker.HiredMerchantWorker;
|
||||
import net.server.worker.MapOwnershipWorker;
|
||||
@@ -211,6 +212,11 @@ public class World {
|
||||
fishingSchedule = tman.register(new FishingWorker(this), 10 * 1000, 10 * 1000);
|
||||
partySearchSchedule = tman.register(new PartySearchWorker(this), 10 * 1000, 10 * 1000);
|
||||
|
||||
if(ServerConstants.USE_FAMILY_SYSTEM) {
|
||||
long timeLeft = Server.getTimeLeftForNextDay();
|
||||
FamilyDailyResetWorker.resetEntitlementUsage(this);
|
||||
tman.register(new FamilyDailyResetWorker(this), 24 * 60 * 60 * 1000, timeLeft);
|
||||
}
|
||||
}
|
||||
|
||||
public int getChannelsSize() {
|
||||
@@ -540,6 +546,12 @@ public class World {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFamily(int id) {
|
||||
synchronized (families) {
|
||||
families.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
public MapleFamily getFamily(int id) {
|
||||
synchronized (families) {
|
||||
@@ -549,6 +561,12 @@ public class World {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<MapleFamily> getFamilies() {
|
||||
synchronized(families) {
|
||||
return Collections.unmodifiableCollection((Collection<MapleFamily>) families.values());
|
||||
}
|
||||
}
|
||||
|
||||
public MapleGuild getGuild(MapleGuildCharacter mgc) {
|
||||
if(mgc == null) return null;
|
||||
@@ -1109,7 +1127,7 @@ public class World {
|
||||
if (isConnected(sender)) {
|
||||
MapleCharacter senderChr = getPlayerStorage().getCharacterByName(sender);
|
||||
if (senderChr != null && senderChr.getMessenger() != null) {
|
||||
if (MapleInviteCoordinator.answerInvite(InviteType.MESSENGER, player.getId(), senderChr.getMessenger().getId(), false).getLeft() == InviteResult.DENIED) {
|
||||
if (MapleInviteCoordinator.answerInvite(InviteType.MESSENGER, player.getId(), senderChr.getMessenger().getId(), false).result == InviteResult.DENIED) {
|
||||
senderChr.getClient().announce(MaplePacketCreator.messengerNote(player.getName(), 5, 0));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user