Project update.

This commit is contained in:
MobiusDev
2015-12-31 23:53:41 +00:00
parent e0d681a17e
commit ad2bcd79be
4084 changed files with 83696 additions and 86998 deletions

View File

@ -0,0 +1,125 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.util.ArrayList;
import java.util.List;
import com.l2jmobius.gameserver.data.xml.impl.SkillTreesData;
import com.l2jmobius.gameserver.model.L2SkillLearn;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.events.ListenersContainer;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.model.interfaces.INamable;
import com.l2jmobius.gameserver.model.zone.type.L2ResidenceZone;
/**
* @author xban1x
*/
public abstract class AbstractResidence extends ListenersContainer implements INamable
{
private final int _residenceId;
private String _name;
private L2ResidenceZone _zone = null;
private final List<SkillHolder> _residentialSkills = new ArrayList<>();
public AbstractResidence(int residenceId)
{
_residenceId = residenceId;
initResidentialSkills();
}
protected abstract void load();
protected abstract void initResidenceZone();
protected void initResidentialSkills()
{
final List<L2SkillLearn> residentialSkills = SkillTreesData.getInstance().getAvailableResidentialSkills(getResidenceId());
for (L2SkillLearn s : residentialSkills)
{
_residentialSkills.add(new SkillHolder(s.getSkillId(), s.getSkillLevel()));
}
}
public final int getResidenceId()
{
return _residenceId;
}
@Override
public final String getName()
{
return _name;
}
// TODO: Remove it later when both castles and forts are loaded from same table.
public final void setName(String name)
{
_name = name;
}
public L2ResidenceZone getResidenceZone()
{
return _zone;
}
protected void setResidenceZone(L2ResidenceZone zone)
{
_zone = zone;
}
public final List<SkillHolder> getResidentialSkills()
{
return _residentialSkills;
}
public void giveResidentialSkills(L2PcInstance player)
{
if ((_residentialSkills != null) && !_residentialSkills.isEmpty())
{
for (SkillHolder sh : _residentialSkills)
{
player.addSkill(sh.getSkill(), false);
}
}
}
public void removeResidentialSkills(L2PcInstance player)
{
if ((_residentialSkills != null) && !_residentialSkills.isEmpty())
{
for (SkillHolder sh : _residentialSkills)
{
player.removeSkill(sh.getSkill(), false);
}
}
}
@Override
public boolean equals(Object obj)
{
return (obj instanceof AbstractResidence) && (((AbstractResidence) obj).getResidenceId() == getResidenceId());
}
@Override
public String toString()
{
return getName() + "(" + getResidenceId() + ")";
}
}

View File

@ -0,0 +1,629 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import static com.l2jmobius.gameserver.model.itemcontainer.Inventory.ADENA_ID;
import static com.l2jmobius.gameserver.model.itemcontainer.Inventory.MAX_ADENA;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Calendar;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.commons.database.pool.impl.ConnectionFactory;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.enums.AuctionItemType;
import com.l2jmobius.gameserver.idfactory.IdFactory;
import com.l2jmobius.gameserver.instancemanager.ClanHallAuctionManager;
import com.l2jmobius.gameserver.instancemanager.ClanHallManager;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.itemcontainer.ItemContainer;
import com.l2jmobius.gameserver.network.SystemMessageId;
public class Auction
{
protected static final Logger _log = Logger.getLogger(Auction.class.getName());
private int _id = 0;
private long _endDate;
private int _highestBidderId = 0;
private String _highestBidderName = "";
private long _highestBidderMaxBid = 0;
private int _itemId = 0;
private String _itemName = "";
private int _itemObjectId = 0;
private final long _itemQuantity = 0;
private String _itemType = "";
private int _sellerId = 0;
private String _sellerClanName = "";
private String _sellerName = "";
private long _currentBid = 0;
private long _startingBid = 0;
private final Map<Integer, Bidder> _bidders = new ConcurrentHashMap<>();
private static final String[] ItemTypeName =
{
"ClanHall"
};
public static class Bidder
{
private final String _name; // TODO replace with objid
private final String _clanName;
private long _bid;
private final Calendar _timeBid;
public Bidder(String name, String clanName, long bid, long timeBid)
{
_name = name;
_clanName = clanName;
_bid = bid;
_timeBid = Calendar.getInstance();
_timeBid.setTimeInMillis(timeBid);
}
public String getName()
{
return _name;
}
public String getClanName()
{
return _clanName;
}
public long getBid()
{
return _bid;
}
public Calendar getTimeBid()
{
return _timeBid;
}
public void setTimeBid(long timeBid)
{
_timeBid.setTimeInMillis(timeBid);
}
public void setBid(long bid)
{
_bid = bid;
}
}
/** Task Sheduler for endAuction */
public class AutoEndTask implements Runnable
{
public AutoEndTask()
{
}
@Override
public void run()
{
try
{
endAuction();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "", e);
}
}
}
/**
* Constructor
* @param auctionId
*/
public Auction(int auctionId)
{
_id = auctionId;
load();
startAutoTask();
}
public Auction(int itemId, L2Clan Clan, long delay, long bid, String name)
{
_id = itemId;
_endDate = System.currentTimeMillis() + delay;
_itemId = itemId;
_itemName = name;
_itemType = "ClanHall";
_sellerId = Clan.getLeaderId();
_sellerName = Clan.getLeaderName();
_sellerClanName = Clan.getName();
_startingBid = bid;
}
/** Load auctions */
private void load()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("Select * from auction where id = ?"))
{
ps.setInt(1, getId());
try (ResultSet rs = ps.executeQuery())
{
while (rs.next())
{
_currentBid = rs.getLong("currentBid");
_endDate = rs.getLong("endDate");
_itemId = rs.getInt("itemId");
_itemName = rs.getString("itemName");
_itemObjectId = rs.getInt("itemObjectId");
_itemType = rs.getString("itemType");
_sellerId = rs.getInt("sellerId");
_sellerClanName = rs.getString("sellerClanName");
_sellerName = rs.getString("sellerName");
_startingBid = rs.getLong("startingBid");
}
}
loadBid();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Exception: Auction.load(): " + e.getMessage(), e);
}
}
/** Load bidders **/
private void loadBid()
{
_highestBidderId = 0;
_highestBidderName = "";
_highestBidderMaxBid = 0;
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT bidderId, bidderName, maxBid, clan_name, time_bid FROM auction_bid WHERE auctionId = ? ORDER BY maxBid DESC"))
{
ps.setInt(1, getId());
try (ResultSet rs = ps.executeQuery())
{
while (rs.next())
{
if (rs.isFirst())
{
_highestBidderId = rs.getInt("bidderId");
_highestBidderName = rs.getString("bidderName");
_highestBidderMaxBid = rs.getLong("maxBid");
}
_bidders.put(rs.getInt("bidderId"), new Bidder(rs.getString("bidderName"), rs.getString("clan_name"), rs.getLong("maxBid"), rs.getLong("time_bid")));
}
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "Exception: Auction.loadBid(): " + e.getMessage(), e);
}
}
/** Task Manage */
private void startAutoTask()
{
final long currentTime = System.currentTimeMillis();
long taskDelay = 0;
if (_endDate <= currentTime)
{
_endDate = currentTime + (7 * 24 * 3600000);
saveAuctionDate();
}
else
{
taskDelay = _endDate - currentTime;
}
ThreadPoolManager.getInstance().scheduleGeneral(new AutoEndTask(), taskDelay);
}
public static String getItemTypeName(AuctionItemType value)
{
return ItemTypeName[value.ordinal()];
}
/** Save Auction Data End */
private void saveAuctionDate()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("Update auction set endDate = ? where id = ?"))
{
ps.setLong(1, _endDate);
ps.setInt(2, _id);
ps.execute();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: saveAuctionDate(): " + e.getMessage(), e);
}
}
/**
* Set a bid
* @param bidder
* @param bid
*/
public synchronized void setBid(L2PcInstance bidder, long bid)
{
long requiredAdena = bid;
if (getHighestBidderName().equals(bidder.getClan().getLeaderName()))
{
requiredAdena = bid - getHighestBidderMaxBid();
}
if (((getHighestBidderId() > 0) && (bid > getHighestBidderMaxBid())) || ((getHighestBidderId() == 0) && (bid >= getStartingBid())))
{
if (takeItem(bidder, requiredAdena))
{
updateInDB(bidder, bid);
bidder.getClan().setAuctionBiddedAt(_id, true);
return;
}
}
if ((bid < getStartingBid()) || (bid <= getHighestBidderMaxBid()))
{
bidder.sendPacket(SystemMessageId.YOUR_BID_PRICE_MUST_BE_HIGHER_THAN_THE_MINIMUM_PRICE_CURRENTLY_BEING_BID);
}
}
/**
* Returns the item to the clan warehouse.
* @param clanName the clan name
* @param quantity the Adena value
* @param penalty if {@code true} fees are applied
*/
private void returnItem(String clanName, long quantity, boolean penalty)
{
if (penalty)
{
quantity *= 0.9; // take 10% tax fee if needed
}
final L2Clan clan = ClanTable.getInstance().getClanByName(clanName);
if (clan == null)
{
_log.warning("Clan " + clanName + " doesn't exist!");
return;
}
final ItemContainer cwh = clan.getWarehouse();
if (cwh == null)
{
_log.warning("There has been a problem with " + clanName + "'s clan warehouse!");
return;
}
// avoid overflow on return
final long limit = MAX_ADENA - cwh.getAdena();
quantity = Math.min(quantity, limit);
cwh.addItem("Outbidded", ADENA_ID, quantity, null, null);
}
/**
* Take Item in WHC
* @param bidder
* @param quantity
* @return
*/
private boolean takeItem(L2PcInstance bidder, long quantity)
{
if ((bidder.getClan() != null) && (bidder.getClan().getWarehouse().getAdena() >= quantity))
{
bidder.getClan().getWarehouse().destroyItemByItemId("Buy", ADENA_ID, quantity, bidder, bidder);
return true;
}
bidder.sendPacket(SystemMessageId.THERE_IS_NOT_ENOUGH_ADENA_IN_THE_CLAN_HALL_WAREHOUSE);
return false;
}
/**
* Update auction in DB
* @param bidder
* @param bid
*/
private void updateInDB(L2PcInstance bidder, long bid)
{
try (Connection con = ConnectionFactory.getInstance().getConnection())
{
if (_bidders.get(bidder.getClanId()) != null)
{
try (PreparedStatement ps = con.prepareStatement("UPDATE auction_bid SET bidderId=?, bidderName=?, maxBid=?, time_bid=? WHERE auctionId=? AND bidderId=?"))
{
ps.setInt(1, bidder.getClanId());
ps.setString(2, bidder.getClan().getLeaderName());
ps.setLong(3, bid);
ps.setLong(4, System.currentTimeMillis());
ps.setInt(5, getId());
ps.setInt(6, bidder.getClanId());
ps.execute();
}
}
else
{
try (PreparedStatement ps = con.prepareStatement("INSERT INTO auction_bid (id, auctionId, bidderId, bidderName, maxBid, clan_name, time_bid) VALUES (?, ?, ?, ?, ?, ?, ?)"))
{
ps.setInt(1, IdFactory.getInstance().getNextId());
ps.setInt(2, getId());
ps.setInt(3, bidder.getClanId());
ps.setString(4, bidder.getName());
ps.setLong(5, bid);
ps.setString(6, bidder.getClan().getName());
ps.setLong(7, System.currentTimeMillis());
ps.execute();
}
if (L2World.getInstance().getPlayer(_highestBidderName) != null)
{
L2World.getInstance().getPlayer(_highestBidderName).sendMessage("You have been out bidded");
}
}
_highestBidderId = bidder.getClanId();
_highestBidderMaxBid = bid;
_highestBidderName = bidder.getClan().getLeaderName();
if (_bidders.get(_highestBidderId) == null)
{
_bidders.put(_highestBidderId, new Bidder(_highestBidderName, bidder.getClan().getName(), bid, Calendar.getInstance().getTimeInMillis()));
}
else
{
_bidders.get(_highestBidderId).setBid(bid);
_bidders.get(_highestBidderId).setTimeBid(Calendar.getInstance().getTimeInMillis());
}
bidder.sendPacket(SystemMessageId.YOUR_BID_HAS_BEEN_SUCCESSFULLY_PLACED);
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: Auction.updateInDB(L2PcInstance bidder, int bid): " + e.getMessage(), e);
}
}
/** Remove bids */
private void removeBids()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("DELETE FROM auction_bid WHERE auctionId=?"))
{
ps.setInt(1, getId());
ps.execute();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: Auction.deleteFromDB(): " + e.getMessage(), e);
}
for (Bidder b : _bidders.values())
{
if (ClanTable.getInstance().getClanByName(b.getClanName()).getHideoutId() == 0)
{
returnItem(b.getClanName(), b.getBid(), true); // 10 % tax
}
else
{
if (L2World.getInstance().getPlayer(b.getName()) != null)
{
L2World.getInstance().getPlayer(b.getName()).sendMessage("Congratulation you have won ClanHall!");
}
}
ClanTable.getInstance().getClanByName(b.getClanName()).setAuctionBiddedAt(0, true);
}
_bidders.clear();
}
/** Remove auctions */
public void deleteAuctionFromDB()
{
ClanHallAuctionManager.getInstance().getAuctions().remove(this);
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("DELETE FROM auction WHERE itemId=?"))
{
ps.setInt(1, _itemId);
ps.execute();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: Auction.deleteFromDB(): " + e.getMessage(), e);
}
}
/** End of auction */
public void endAuction()
{
if (ClanHallManager.getInstance().loaded())
{
if ((_highestBidderId == 0) && (_sellerId == 0))
{
startAutoTask();
return;
}
if ((_highestBidderId == 0) && (_sellerId > 0))
{
/**
* If seller haven't sell ClanHall, auction removed, THIS MUST BE CONFIRMED
*/
final int aucId = ClanHallAuctionManager.getInstance().getAuctionIndex(_id);
ClanHallAuctionManager.getInstance().getAuctions().remove(aucId);
return;
}
if (_sellerId > 0)
{
returnItem(_sellerClanName, _highestBidderMaxBid, true);
returnItem(_sellerClanName, ClanHallManager.getInstance().getAuctionableHallById(_itemId).getLease(), false);
}
deleteAuctionFromDB();
final L2Clan Clan = ClanTable.getInstance().getClanByName(_bidders.get(_highestBidderId).getClanName());
_bidders.remove(_highestBidderId);
Clan.setAuctionBiddedAt(0, true);
removeBids();
ClanHallManager.getInstance().setOwner(_itemId, Clan);
}
else
{
/** Task waiting ClanHallManager is loaded every 3s */
ThreadPoolManager.getInstance().scheduleGeneral(new AutoEndTask(), 3000);
}
}
/**
* Cancel bid
* @param bidder
*/
public synchronized void cancelBid(int bidder)
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("DELETE FROM auction_bid WHERE auctionId=? AND bidderId=?"))
{
ps.setInt(1, getId());
ps.setInt(2, bidder);
ps.execute();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: Auction.cancelBid(String bidder): " + e.getMessage(), e);
}
returnItem(_bidders.get(bidder).getClanName(), _bidders.get(bidder).getBid(), true);
ClanTable.getInstance().getClanByName(_bidders.get(bidder).getClanName()).setAuctionBiddedAt(0, true);
_bidders.clear();
loadBid();
}
/** Cancel auction */
public void cancelAuction()
{
deleteAuctionFromDB();
removeBids();
}
/** Confirm an auction */
public void confirmAuction()
{
ClanHallAuctionManager.getInstance().getAuctions().add(this);
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("INSERT INTO auction (id, sellerId, sellerName, sellerClanName, itemType, itemId, itemObjectId, itemName, itemQuantity, startingBid, currentBid, endDate) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"))
{
ps.setInt(1, getId());
ps.setInt(2, _sellerId);
ps.setString(3, _sellerName);
ps.setString(4, _sellerClanName);
ps.setString(5, _itemType);
ps.setInt(6, _itemId);
ps.setInt(7, _itemObjectId);
ps.setString(8, _itemName);
ps.setLong(9, _itemQuantity);
ps.setLong(10, _startingBid);
ps.setLong(11, _currentBid);
ps.setLong(12, _endDate);
ps.execute();
ps.close();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: Auction.load(): " + e.getMessage(), e);
}
}
/**
* Get var auction
* @return
*/
public final int getId()
{
return _id;
}
public final long getCurrentBid()
{
return _currentBid;
}
public final long getEndDate()
{
return _endDate;
}
public final int getHighestBidderId()
{
return _highestBidderId;
}
public final String getHighestBidderName()
{
return _highestBidderName;
}
public final long getHighestBidderMaxBid()
{
return _highestBidderMaxBid;
}
public final int getItemId()
{
return _itemId;
}
public final String getItemName()
{
return _itemName;
}
public final int getItemObjectId()
{
return _itemObjectId;
}
public final long getItemQuantity()
{
return _itemQuantity;
}
public final String getItemType()
{
return _itemType;
}
public final int getSellerId()
{
return _sellerId;
}
public final String getSellerName()
{
return _sellerName;
}
public final String getSellerClanName()
{
return _sellerClanName;
}
public final long getStartingBid()
{
return _startingBid;
}
public final Map<Integer, Bidder> getBidders()
{
return _bidders;
}
}

View File

@ -0,0 +1,779 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.datatables.SkillData;
import com.l2jmobius.gameserver.datatables.SpawnTable;
import com.l2jmobius.gameserver.enums.Team;
import com.l2jmobius.gameserver.instancemanager.HandysBlockCheckerManager;
import com.l2jmobius.gameserver.model.ArenaParticipantsHolder;
import com.l2jmobius.gameserver.model.L2Spawn;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.actor.L2Summon;
import com.l2jmobius.gameserver.model.actor.instance.L2BlockInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.itemcontainer.PcInventory;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.model.zone.ZoneId;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.ExBasicActionList;
import com.l2jmobius.gameserver.network.serverpackets.ExCubeGameChangePoints;
import com.l2jmobius.gameserver.network.serverpackets.ExCubeGameCloseUI;
import com.l2jmobius.gameserver.network.serverpackets.ExCubeGameEnd;
import com.l2jmobius.gameserver.network.serverpackets.ExCubeGameExtendedChangePoints;
import com.l2jmobius.gameserver.network.serverpackets.RelationChanged;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.util.Rnd;
/**
* @author BiggBoss
*/
public final class BlockCheckerEngine
{
protected static final Logger _log = Logger.getLogger(BlockCheckerEngine.class.getName());
// The object which holds all basic members info
protected ArenaParticipantsHolder _holder;
// Maps to hold player of each team and his points
protected Map<L2PcInstance, Integer> _redTeamPoints = new ConcurrentHashMap<>();
protected Map<L2PcInstance, Integer> _blueTeamPoints = new ConcurrentHashMap<>();
// The initial points of the event
protected int _redPoints = 15;
protected int _bluePoints = 15;
// Current used arena
protected int _arena = -1;
// All blocks
protected List<L2Spawn> _spawns = new CopyOnWriteArrayList<>();
// Sets if the red team won the event at the end of this (used for packets)
protected boolean _isRedWinner;
// Time when the event starts. Used on packet sending
protected long _startedTime;
// The needed arena coordinates
// Arena X: team1X, team1Y, team2X, team2Y, ArenaCenterX, ArenaCenterY
protected static final int[][] _arenaCoordinates =
{
// Arena 0 - Team 1 XY, Team 2 XY - CENTER XY
{
-58368,
-62745,
-57751,
-62131,
-58053,
-62417
},
// Arena 1 - Team 1 XY, Team 2 XY - CENTER XY
{
-58350,
-63853,
-57756,
-63266,
-58053,
-63551
},
// Arena 2 - Team 1 XY, Team 2 XY - CENTER XY
{
-57194,
-63861,
-56580,
-63249,
-56886,
-63551
},
// Arena 3 - Team 1 XY, Team 2 XY - CENTER XY
{
-57200,
-62727,
-56584,
-62115,
-56850,
-62391
}
};
// Common z coordinate
private static final int _zCoord = -2405;
// List of dropped items in event (for later deletion)
protected List<L2ItemInstance> _drops = new CopyOnWriteArrayList<>();
// Default arena
private static final byte DEFAULT_ARENA = -1;
// Event is started
protected boolean _isStarted = false;
// Event end
protected ScheduledFuture<?> _task;
// Preserve from exploit reward by logging out
protected boolean _abnormalEnd = false;
public BlockCheckerEngine(ArenaParticipantsHolder holder, int arena)
{
_holder = holder;
if ((arena > -1) && (arena < 4))
{
_arena = arena;
}
for (L2PcInstance player : holder.getRedPlayers())
{
_redTeamPoints.put(player, 0);
}
for (L2PcInstance player : holder.getBluePlayers())
{
_blueTeamPoints.put(player, 0);
}
}
/**
* Updates the player holder before the event starts to synchronize all info
* @param holder
*/
public void updatePlayersOnStart(ArenaParticipantsHolder holder)
{
_holder = holder;
}
/**
* Returns the current holder object of this object engine
* @return HandysBlockCheckerManager.ArenaParticipantsHolder
*/
public ArenaParticipantsHolder getHolder()
{
return _holder;
}
/**
* Will return the id of the arena used by this event
* @return false;
*/
public int getArena()
{
return _arena;
}
/**
* Returns the time when the event started
* @return long
*/
public long getStarterTime()
{
return _startedTime;
}
/**
* Returns the current red team points
* @return int
*/
public int getRedPoints()
{
synchronized (this)
{
return _redPoints;
}
}
/**
* Returns the current blue team points
* @return int
*/
public int getBluePoints()
{
synchronized (this)
{
return _bluePoints;
}
}
/**
* Returns the player points
* @param player
* @param isRed
* @return int
*/
public int getPlayerPoints(L2PcInstance player, boolean isRed)
{
if (!_redTeamPoints.containsKey(player) && !_blueTeamPoints.containsKey(player))
{
return 0;
}
if (isRed)
{
return _redTeamPoints.get(player);
}
return _blueTeamPoints.get(player);
}
/**
* Increases player points for his teams
* @param player
* @param team
*/
public synchronized void increasePlayerPoints(L2PcInstance player, int team)
{
if (player == null)
{
return;
}
if (team == 0)
{
final int points = _redTeamPoints.get(player) + 1;
_redTeamPoints.put(player, points);
_redPoints++;
_bluePoints--;
}
else
{
final int points = _blueTeamPoints.get(player) + 1;
_blueTeamPoints.put(player, points);
_bluePoints++;
_redPoints--;
}
}
/**
* Will add a new drop into the list of dropped items
* @param item
*/
public void addNewDrop(L2ItemInstance item)
{
if (item != null)
{
_drops.add(item);
}
}
/**
* Will return true if the event is already started
* @return boolean
*/
public boolean isStarted()
{
return _isStarted;
}
/**
* Will send all packets for the event members with the relation info
* @param plr
*/
protected void broadcastRelationChanged(L2PcInstance plr)
{
for (L2PcInstance p : _holder.getAllPlayers())
{
p.sendPacket(new RelationChanged(plr, plr.getRelation(p), plr.isAutoAttackable(p)));
}
}
/**
* Called when a there is an empty team. The event will end.
*/
public void endEventAbnormally()
{
try
{
synchronized (this)
{
_isStarted = false;
if (_task != null)
{
_task.cancel(true);
}
_abnormalEnd = true;
ThreadPoolManager.getInstance().executeGeneral(new EndEvent());
if (Config.DEBUG)
{
_log.config("Handys Block Checker Event at arena " + _arena + " ended due lack of players!");
}
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Couldnt end Block Checker event at " + _arena, e);
}
}
/**
* This inner class set ups all player and arena parameters to start the event
*/
public class StartEvent implements Runnable
{
// In event used skills
private final Skill _freeze, _transformationRed, _transformationBlue;
// Common and unparametizer packet
private final ExCubeGameCloseUI _closeUserInterface = new ExCubeGameCloseUI();
public StartEvent()
{
// Initialize all used skills
_freeze = SkillData.getInstance().getSkill(6034, 1);
_transformationRed = SkillData.getInstance().getSkill(6035, 1);
_transformationBlue = SkillData.getInstance().getSkill(6036, 1);
}
/**
* Will set up all player parameters and port them to their respective location based on their teams
*/
private void setUpPlayers()
{
// Set current arena as being used
HandysBlockCheckerManager.getInstance().setArenaBeingUsed(_arena);
// Initialize packets avoiding create a new one per player
_redPoints = _spawns.size() / 2;
_bluePoints = _spawns.size() / 2;
final ExCubeGameChangePoints initialPoints = new ExCubeGameChangePoints(300, _bluePoints, _redPoints);
ExCubeGameExtendedChangePoints clientSetUp;
for (L2PcInstance player : _holder.getAllPlayers())
{
if (player == null)
{
continue;
}
// Send the secret client packet set up
final boolean isRed = _holder.getRedPlayers().contains(player);
clientSetUp = new ExCubeGameExtendedChangePoints(300, _bluePoints, _redPoints, isRed, player, 0);
player.sendPacket(clientSetUp);
player.sendPacket(ActionFailed.STATIC_PACKET);
// Teleport Player - Array access
// Team 0 * 2 = 0; 0 = 0, 0 + 1 = 1.
// Team 1 * 2 = 2; 2 = 2, 2 + 1 = 3
final int tc = _holder.getPlayerTeam(player) * 2;
// Get x and y coordinates
final int x = _arenaCoordinates[_arena][tc];
final int y = _arenaCoordinates[_arena][tc + 1];
player.teleToLocation(x, y, _zCoord);
// Set the player team
if (isRed)
{
_redTeamPoints.put(player, 0);
player.setTeam(Team.RED);
}
else
{
_blueTeamPoints.put(player, 0);
player.setTeam(Team.BLUE);
}
player.stopAllEffects();
final L2Summon pet = player.getPet();
if (pet != null)
{
pet.unSummon(player);
}
player.getServitors().values().forEach(s -> s.unSummon(player));
// Give the player start up effects
// Freeze
_freeze.applyEffects(player, player);
// Transformation
if (_holder.getPlayerTeam(player) == 0)
{
_transformationRed.applyEffects(player, player);
}
else
{
_transformationBlue.applyEffects(player, player);
}
// Set the current player arena
player.setBlockCheckerArena((byte) _arena);
player.setInsideZone(ZoneId.PVP, true);
// Send needed packets
player.sendPacket(initialPoints);
player.sendPacket(_closeUserInterface);
// ExBasicActionList
player.sendPacket(ExBasicActionList.STATIC_PACKET);
broadcastRelationChanged(player);
}
}
@Override
public void run()
{
// Wrong arena passed, stop event
if (_arena == -1)
{
_log.severe("Couldnt set up the arena Id for the Block Checker event, cancelling event...");
return;
}
_isStarted = true;
// Spawn the blocks
ThreadPoolManager.getInstance().executeGeneral(new SpawnRound(16, 1));
// Start up player parameters
setUpPlayers();
// Set the started time
_startedTime = System.currentTimeMillis() + 300000;
}
}
/**
* This class spawns the second round of boxes and schedules the event end
*/
private class SpawnRound implements Runnable
{
int _numOfBoxes;
int _round;
SpawnRound(int numberOfBoxes, int round)
{
_numOfBoxes = numberOfBoxes;
_round = round;
}
@Override
public void run()
{
if (!_isStarted)
{
return;
}
switch (_round)
{
case 1: // Schedule second spawn round
{
_task = ThreadPoolManager.getInstance().scheduleGeneral(new SpawnRound(20, 2), 60000);
break;
}
case 2: // Schedule third spawn round
{
_task = ThreadPoolManager.getInstance().scheduleGeneral(new SpawnRound(14, 3), 60000);
break;
}
case 3: // Schedule Event End Count Down
{
_task = ThreadPoolManager.getInstance().scheduleGeneral(new EndEvent(), 180000);
break;
}
}
// random % 2, if == 0 will spawn a red block
// if != 0, will spawn a blue block
byte random = 2;
// Spawn blocks
try
{
// Creates 50 new blocks
for (int i = 0; i < _numOfBoxes; i++)
{
final L2Spawn spawn = new L2Spawn(18672);
spawn.setX(_arenaCoordinates[_arena][4] + Rnd.get(-400, 400));
spawn.setY(_arenaCoordinates[_arena][5] + Rnd.get(-400, 400));
spawn.setZ(_zCoord);
spawn.setAmount(1);
spawn.setHeading(1);
spawn.setRespawnDelay(1);
SpawnTable.getInstance().addNewSpawn(spawn, false);
spawn.init();
final L2BlockInstance block = (L2BlockInstance) spawn.getLastSpawn();
// switch color
if ((random % 2) == 0)
{
block.setRed(true);
}
else
{
block.setRed(false);
}
block.disableCoreAI(true);
_spawns.add(spawn);
random++;
}
}
catch (Exception e)
{
_log.warning(getClass().getSimpleName() + ": " + e.getMessage());
}
// Spawn the block carrying girl
if ((_round == 1) || (_round == 2))
{
try
{
final L2Spawn girlSpawn = new L2Spawn(18676);
girlSpawn.setX(_arenaCoordinates[_arena][4] + Rnd.get(-400, 400));
girlSpawn.setY(_arenaCoordinates[_arena][5] + Rnd.get(-400, 400));
girlSpawn.setZ(_zCoord);
girlSpawn.setAmount(1);
girlSpawn.setHeading(1);
girlSpawn.setRespawnDelay(1);
SpawnTable.getInstance().addNewSpawn(girlSpawn, false);
girlSpawn.init();
// Schedule his deletion after 9 secs of spawn
ThreadPoolManager.getInstance().scheduleGeneral(new CarryingGirlUnspawn(girlSpawn), 9000);
}
catch (Exception e)
{
_log.warning("Couldnt Spawn Block Checker NPCs! Wrong instance type at npc table?");
_log.warning(getClass().getSimpleName() + ": " + e.getMessage());
}
}
_redPoints += _numOfBoxes / 2;
_bluePoints += _numOfBoxes / 2;
final int timeLeft = (int) ((getStarterTime() - System.currentTimeMillis()) / 1000);
final ExCubeGameChangePoints changePoints = new ExCubeGameChangePoints(timeLeft, getBluePoints(), getRedPoints());
getHolder().broadCastPacketToTeam(changePoints);
}
}
private class CarryingGirlUnspawn implements Runnable
{
private final L2Spawn _spawn;
protected CarryingGirlUnspawn(L2Spawn spawn)
{
_spawn = spawn;
}
@Override
public void run()
{
if (_spawn == null)
{
_log.warning("HBCE: Block Carrying Girl is null");
return;
}
SpawnTable.getInstance().deleteSpawn(_spawn, false);
_spawn.stopRespawn();
_spawn.getLastSpawn().deleteMe();
}
}
/*
* private class CountDown implements Runnable {
* @Override public void run() { _holder.broadCastPacketToTeam(SystemMessage.getSystemMessage(SystemMessageId.BLOCK_CHECKER_ENDS_5)); ThreadPoolManager.getInstance().scheduleGeneral(new EndEvent(), 5000); } }
*/
/**
* This class erase all event parameters on player and port them back near Handy. Also, unspawn blocks, runs a garbage collector and set as free the used arena
*/
protected class EndEvent implements Runnable
{
// Garbage collector and arena free setter
private void clearMe()
{
HandysBlockCheckerManager.getInstance().clearPaticipantQueueByArenaId(_arena);
_holder.clearPlayers();
_blueTeamPoints.clear();
_redTeamPoints.clear();
HandysBlockCheckerManager.getInstance().setArenaFree(_arena);
for (L2Spawn spawn : _spawns)
{
spawn.stopRespawn();
spawn.getLastSpawn().deleteMe();
SpawnTable.getInstance().deleteSpawn(spawn, false);
}
_spawns.clear();
for (L2ItemInstance item : _drops)
{
// a player has it, it will be deleted later
if (!item.isVisible() || (item.getOwnerId() != 0))
{
continue;
}
item.decayMe();
L2World.getInstance().removeObject(item);
}
_drops.clear();
}
/**
* Reward players after event. Tie - No Reward
*/
private void rewardPlayers()
{
if (_redPoints == _bluePoints)
{
return;
}
_isRedWinner = _redPoints > _bluePoints ? true : false;
if (_isRedWinner)
{
rewardAsWinner(true);
rewardAsLooser(false);
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.THE_C1_TEAM_HAS_WON);
msg.addString("Red Team");
_holder.broadCastPacketToTeam(msg);
}
else if (_bluePoints > _redPoints)
{
rewardAsWinner(false);
rewardAsLooser(true);
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.THE_C1_TEAM_HAS_WON);
msg.addString("Blue Team");
_holder.broadCastPacketToTeam(msg);
}
else
{
rewardAsLooser(true);
rewardAsLooser(false);
}
}
/**
* Reward the specified team as a winner team 1) Higher score - 8 extra 2) Higher score - 5 extra
* @param isRed
*/
private void rewardAsWinner(boolean isRed)
{
final Map<L2PcInstance, Integer> tempPoints = isRed ? _redTeamPoints : _blueTeamPoints;
// Main give
for (Entry<L2PcInstance, Integer> points : tempPoints.entrySet())
{
if (points.getKey() == null)
{
continue;
}
if (points.getValue() >= 10)
{
points.getKey().addItem("Block Checker", 13067, 2, points.getKey(), true);
}
else
{
tempPoints.remove(points.getKey());
}
}
int first = 0, second = 0;
L2PcInstance winner1 = null, winner2 = null;
for (Entry<L2PcInstance, Integer> entry : tempPoints.entrySet())
{
final L2PcInstance pc = entry.getKey();
final int pcPoints = entry.getValue();
if (pcPoints > first)
{
// Move old data
second = first;
winner2 = winner1;
// Set new data
first = pcPoints;
winner1 = pc;
}
else if (pcPoints > second)
{
second = pcPoints;
winner2 = pc;
}
}
if (winner1 != null)
{
winner1.addItem("Block Checker", 13067, 8, winner1, true);
}
if (winner2 != null)
{
winner2.addItem("Block Checker", 13067, 5, winner2, true);
}
}
/**
* Will reward the looser team with the predefined rewards Player got >= 10 points: 2 coins Player got < 10 points: 0 coins
* @param isRed
*/
private void rewardAsLooser(boolean isRed)
{
final Map<L2PcInstance, Integer> tempPoints = isRed ? _redTeamPoints : _blueTeamPoints;
for (Entry<L2PcInstance, Integer> entry : tempPoints.entrySet())
{
final L2PcInstance player = entry.getKey();
if ((player != null) && (entry.getValue() >= 10))
{
player.addItem("Block Checker", 13067, 2, player, true);
}
}
}
/**
* Teleport players back, give status back and send final packet
*/
private void setPlayersBack()
{
final ExCubeGameEnd end = new ExCubeGameEnd(_isRedWinner);
for (L2PcInstance player : _holder.getAllPlayers())
{
if (player == null)
{
continue;
}
player.stopAllEffects();
// Remove team aura
player.setTeam(Team.NONE);
// Set default arena
player.setBlockCheckerArena(DEFAULT_ARENA);
// Remove the event items
final PcInventory inv = player.getInventory();
if (inv.getItemByItemId(13787) != null)
{
final long count = inv.getInventoryItemCount(13787, 0);
inv.destroyItemByItemId("Handys Block Checker", 13787, count, player, player);
}
if (inv.getItemByItemId(13788) != null)
{
final long count = inv.getInventoryItemCount(13788, 0);
inv.destroyItemByItemId("Handys Block Checker", 13788, count, player, player);
}
broadcastRelationChanged(player);
// Teleport Back
player.teleToLocation(-57478, -60367, -2370);
player.setInsideZone(ZoneId.PVP, false);
// Send end packet
player.sendPacket(end);
player.broadcastUserInfo();
}
}
@Override
public void run()
{
if (!_abnormalEnd)
{
rewardPlayers();
}
setPlayersBack();
clearMe();
_isStarted = false;
_abnormalEnd = false;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,553 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.commons.database.pool.impl.ConnectionFactory;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.zone.type.L2ClanHallZone;
import com.l2jmobius.gameserver.network.serverpackets.PledgeShowInfoUpdate;
public abstract class ClanHall
{
protected static final Logger _log = Logger.getLogger(ClanHall.class.getName());
private final int _clanHallId;
private ArrayList<L2DoorInstance> _doors;
private final String _name;
private int _ownerId;
private final String _desc;
private final String _location;
private L2ClanHallZone _zone;
protected boolean _isFree = true;
private final Map<Integer, ClanHallFunction> _functions;
/** Clan Hall Functions */
public static final int FUNC_TELEPORT = 1;
public static final int FUNC_ITEM_CREATE = 2;
public static final int FUNC_RESTORE_HP = 3;
public static final int FUNC_RESTORE_MP = 4;
public static final int FUNC_RESTORE_EXP = 5;
public static final int FUNC_SUPPORT = 6;
public static final int FUNC_DECO_FRONTPLATEFORM = 7; // Only Auctionable Halls
public static final int FUNC_DECO_CURTAINS = 8; // Only Auctionable Halls
public class ClanHallFunction
{
private final int _type;
private int _lvl;
protected int _fee;
protected int _tempFee;
private final long _rate;
private long _endDate;
protected boolean _inDebt;
public boolean _cwh; // first activating clanhall function is payed from player inventory, any others from clan warehouse
public ClanHallFunction(int type, int lvl, int lease, int tempLease, long rate, long time, boolean cwh)
{
_type = type;
_lvl = lvl;
_fee = lease;
_tempFee = tempLease;
_rate = rate;
_endDate = time;
initializeTask(cwh);
}
public int getType()
{
return _type;
}
public int getLvl()
{
return _lvl;
}
public int getLease()
{
return _fee;
}
public long getRate()
{
return _rate;
}
public long getEndTime()
{
return _endDate;
}
public void setLvl(int lvl)
{
_lvl = lvl;
}
public void setLease(int lease)
{
_fee = lease;
}
public void setEndTime(long time)
{
_endDate = time;
}
private void initializeTask(boolean cwh)
{
if (_isFree)
{
return;
}
final long currentTime = System.currentTimeMillis();
if (_endDate > currentTime)
{
ThreadPoolManager.getInstance().scheduleGeneral(new FunctionTask(cwh), _endDate - currentTime);
}
else
{
ThreadPoolManager.getInstance().scheduleGeneral(new FunctionTask(cwh), 0);
}
}
private class FunctionTask implements Runnable
{
public FunctionTask(boolean cwh)
{
_cwh = cwh;
}
@Override
public void run()
{
try
{
if (_isFree)
{
return;
}
if ((ClanTable.getInstance().getClan(getOwnerId()).getWarehouse().getAdena() >= _fee) || !_cwh)
{
int fee = _fee;
if (getEndTime() == -1)
{
fee = _tempFee;
}
setEndTime(System.currentTimeMillis() + getRate());
dbSave();
if (_cwh)
{
ClanTable.getInstance().getClan(getOwnerId()).getWarehouse().destroyItemByItemId("CH_function_fee", Inventory.ADENA_ID, fee, null, null);
}
ThreadPoolManager.getInstance().scheduleGeneral(new FunctionTask(true), getRate());
}
else
{
removeFunction(getType());
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "", e);
}
}
}
public void dbSave()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("REPLACE INTO clanhall_functions (hall_id, type, lvl, lease, rate, endTime) VALUES (?,?,?,?,?,?)"))
{
ps.setInt(1, getId());
ps.setInt(2, getType());
ps.setInt(3, getLvl());
ps.setInt(4, getLease());
ps.setLong(5, getRate());
ps.setLong(6, getEndTime());
ps.execute();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: ClanHall.updateFunctions(int type, int lvl, int lease, long rate, long time, boolean addNew): " + e.getMessage(), e);
}
}
}
public ClanHall(StatsSet set)
{
_clanHallId = set.getInt("id");
_name = set.getString("name");
_ownerId = set.getInt("ownerId");
_desc = set.getString("desc");
_location = set.getString("location");
_functions = new ConcurrentHashMap<>();
if (_ownerId > 0)
{
final L2Clan clan = ClanTable.getInstance().getClan(_ownerId);
if (clan != null)
{
clan.setHideoutId(getId());
}
else
{
free();
}
}
}
/**
* @return Id Of Clan hall
*/
public final int getId()
{
return _clanHallId;
}
/**
* @return the Clan Hall name.
*/
public final String getName()
{
return _name;
}
/**
* @return OwnerId
*/
public final int getOwnerId()
{
return _ownerId;
}
/**
* @return Desc
*/
public final String getDesc()
{
return _desc;
}
/**
* @return Location
*/
public final String getLocation()
{
return _location;
}
/**
* @return all DoorInstance
*/
public final ArrayList<L2DoorInstance> getDoors()
{
if (_doors == null)
{
_doors = new ArrayList<>();
}
return _doors;
}
/**
* @param doorId
* @return Door
*/
public final L2DoorInstance getDoor(int doorId)
{
if (doorId <= 0)
{
return null;
}
for (L2DoorInstance door : getDoors())
{
if (door.getId() == doorId)
{
return door;
}
}
return null;
}
/**
* @param type
* @return function with id
*/
public ClanHallFunction getFunction(int type)
{
return _functions.get(type);
}
/**
* Sets this clan halls zone
* @param zone
*/
public void setZone(L2ClanHallZone zone)
{
_zone = zone;
}
/**
* @param x
* @param y
* @param z
* @return true if object is inside the zone
*/
public boolean checkIfInZone(int x, int y, int z)
{
return getZone().isInsideZone(x, y, z);
}
/**
* @return the zone of this clan hall
*/
public L2ClanHallZone getZone()
{
return _zone;
}
/** Free this clan hall */
public void free()
{
_ownerId = 0;
_isFree = true;
for (Integer fc : _functions.keySet())
{
removeFunction(fc);
}
_functions.clear();
updateDb();
}
/**
* Set owner if clan hall is free
* @param clan
*/
public void setOwner(L2Clan clan)
{
// Verify that this ClanHall is Free and Clan isn't null
if ((_ownerId > 0) || (clan == null))
{
return;
}
_ownerId = clan.getId();
_isFree = false;
clan.setHideoutId(getId());
// Announce to Online member new ClanHall
clan.broadcastToOnlineMembers(new PledgeShowInfoUpdate(clan));
updateDb();
}
/**
* Open or Close Door
* @param activeChar
* @param doorId
* @param open
*/
public void openCloseDoor(L2PcInstance activeChar, int doorId, boolean open)
{
if ((activeChar != null) && (activeChar.getClanId() == getOwnerId()))
{
openCloseDoor(doorId, open);
}
}
public void openCloseDoor(int doorId, boolean open)
{
openCloseDoor(getDoor(doorId), open);
}
public void openCloseDoor(L2DoorInstance door, boolean open)
{
if (door != null)
{
if (open)
{
door.openMe();
}
else
{
door.closeMe();
}
}
}
public void openCloseDoors(L2PcInstance activeChar, boolean open)
{
if ((activeChar != null) && (activeChar.getClanId() == getOwnerId()))
{
openCloseDoors(open);
}
}
public void openCloseDoors(boolean open)
{
for (L2DoorInstance door : getDoors())
{
if (door != null)
{
if (open)
{
door.openMe();
}
else
{
door.closeMe();
}
}
}
}
/** Banish Foreigner */
public void banishForeigners()
{
if (_zone != null)
{
_zone.banishForeigners(getOwnerId());
}
else
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Zone is null for clan hall: " + getId() + " " + getName());
}
}
/** Load All Functions */
protected void loadFunctions()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT * FROM clanhall_functions WHERE hall_id = ?"))
{
ps.setInt(1, getId());
try (ResultSet rs = ps.executeQuery())
{
while (rs.next())
{
_functions.put(rs.getInt("type"), new ClanHallFunction(rs.getInt("type"), rs.getInt("lvl"), rs.getInt("lease"), 0, rs.getLong("rate"), rs.getLong("endTime"), true));
}
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: ClanHall.loadFunctions(): " + e.getMessage(), e);
}
}
/**
* Remove function In List and in DB
* @param functionType
*/
public void removeFunction(int functionType)
{
_functions.remove(functionType);
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("DELETE FROM clanhall_functions WHERE hall_id=? AND type=?"))
{
ps.setInt(1, getId());
ps.setInt(2, functionType);
ps.execute();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: ClanHall.removeFunctions(int functionType): " + e.getMessage(), e);
}
}
public boolean updateFunctions(L2PcInstance player, int type, int lvl, int lease, long rate, boolean addNew)
{
if (player == null)
{
return false;
}
if (lease > 0)
{
if (!player.destroyItemByItemId("Consume", Inventory.ADENA_ID, lease, null, true))
{
return false;
}
}
if (addNew)
{
_functions.put(type, new ClanHallFunction(type, lvl, lease, 0, rate, 0, false));
}
else
{
if ((lvl == 0) && (lease == 0))
{
removeFunction(type);
}
else
{
final int diffLease = lease - _functions.get(type).getLease();
if (diffLease > 0)
{
_functions.remove(type);
_functions.put(type, new ClanHallFunction(type, lvl, lease, 0, rate, -1, false));
}
else
{
_functions.get(type).setLease(lease);
_functions.get(type).setLvl(lvl);
_functions.get(type).dbSave();
}
}
}
return true;
}
public int getGrade()
{
return 0;
}
public long getPaidUntil()
{
return 0;
}
public int getLease()
{
return 0;
}
public boolean isSiegableHall()
{
return false;
}
public boolean isFree()
{
return _isFree;
}
public abstract void updateDb();
}

View File

@ -0,0 +1,167 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.commons.database.pool.impl.ConnectionFactory;
import com.l2jmobius.gameserver.idfactory.IdFactory;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
/**
* @author evill33t
*/
public class Couple
{
private static final Logger _log = Logger.getLogger(Couple.class.getName());
private int _Id = 0;
private int _player1Id = 0;
private int _player2Id = 0;
private boolean _maried = false;
private Calendar _affiancedDate;
private Calendar _weddingDate;
public Couple(int coupleId)
{
_Id = coupleId;
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT * FROM mods_wedding WHERE id = ?"))
{
ps.setInt(1, _Id);
try (ResultSet rs = ps.executeQuery())
{
while (rs.next())
{
_player1Id = rs.getInt("player1Id");
_player2Id = rs.getInt("player2Id");
_maried = rs.getBoolean("married");
_affiancedDate = Calendar.getInstance();
_affiancedDate.setTimeInMillis(rs.getLong("affianceDate"));
_weddingDate = Calendar.getInstance();
_weddingDate.setTimeInMillis(rs.getLong("weddingDate"));
}
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: Couple.load(): " + e.getMessage(), e);
}
}
public Couple(L2PcInstance player1, L2PcInstance player2)
{
final int _tempPlayer1Id = player1.getObjectId();
final int _tempPlayer2Id = player2.getObjectId();
_player1Id = _tempPlayer1Id;
_player2Id = _tempPlayer2Id;
_affiancedDate = Calendar.getInstance();
_affiancedDate.setTimeInMillis(Calendar.getInstance().getTimeInMillis());
_weddingDate = Calendar.getInstance();
_weddingDate.setTimeInMillis(Calendar.getInstance().getTimeInMillis());
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("INSERT INTO mods_wedding (id, player1Id, player2Id, married, affianceDate, weddingDate) VALUES (?, ?, ?, ?, ?, ?)"))
{
_Id = IdFactory.getInstance().getNextId();
ps.setInt(1, _Id);
ps.setInt(2, _player1Id);
ps.setInt(3, _player2Id);
ps.setBoolean(4, false);
ps.setLong(5, _affiancedDate.getTimeInMillis());
ps.setLong(6, _weddingDate.getTimeInMillis());
ps.execute();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Could not create couple: " + e.getMessage(), e);
}
}
public void marry()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("UPDATE mods_wedding set married = ?, weddingDate = ? where id = ?"))
{
ps.setBoolean(1, true);
_weddingDate = Calendar.getInstance();
ps.setLong(2, _weddingDate.getTimeInMillis());
ps.setInt(3, _Id);
ps.execute();
_maried = true;
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Could not marry: " + e.getMessage(), e);
}
}
public void divorce()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("DELETE FROM mods_wedding WHERE id=?"))
{
ps.setInt(1, _Id);
ps.execute();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Exception: Couple.divorce(): " + e.getMessage(), e);
}
}
public final int getId()
{
return _Id;
}
public final int getPlayer1Id()
{
return _player1Id;
}
public final int getPlayer2Id()
{
return _player2Id;
}
public final boolean getMaried()
{
return _maried;
}
public final Calendar getAffiancedDate()
{
return _affiancedDate;
}
public final Calendar getWeddingDate()
{
return _weddingDate;
}
}

View File

@ -0,0 +1,831 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.enums.DuelResult;
import com.l2jmobius.gameserver.enums.DuelState;
import com.l2jmobius.gameserver.enums.Team;
import com.l2jmobius.gameserver.instancemanager.DuelManager;
import com.l2jmobius.gameserver.instancemanager.InstanceManager;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Summon;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.model.zone.ZoneId;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.ExDuelEnd;
import com.l2jmobius.gameserver.network.serverpackets.ExDuelReady;
import com.l2jmobius.gameserver.network.serverpackets.ExDuelStart;
import com.l2jmobius.gameserver.network.serverpackets.ExDuelUpdateUserInfo;
import com.l2jmobius.gameserver.network.serverpackets.L2GameServerPacket;
import com.l2jmobius.gameserver.network.serverpackets.PlaySound;
import com.l2jmobius.gameserver.network.serverpackets.SocialAction;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/**
* @author Zealar
*/
public class Duel
{
protected static final Logger _log = Logger.getLogger(Duel.class.getName());
private static final PlaySound B04_S01 = new PlaySound(1, "B04_S01", 0, 0, 0, 0, 0);
private static final int PARTY_DUEL_DURATION = 300;
private static final int PARTY_DUEL_PREPARE_TIME = 30;
private static final int PARTY_DUEL_TELEPORT_BACK_TIME = 10 * 1000;
private static final int PLAYER_DUEL_DURATION = 120;
private static final int DUEL_PREPARE_TIME = 5;
private final int _duelId;
private final List<L2PcInstance> _teamA;
private final L2PcInstance _leaderA;
private final List<L2PcInstance> _teamB;
private final L2PcInstance _leaderB;
private final boolean _partyDuel;
private final Calendar _duelEndTime;
private int _surrenderRequest = 0;
private int _countdown;
private final Map<Integer, PlayerCondition> _playerConditions = new ConcurrentHashMap<>();
private int _duelInstanceId;
public Duel(L2PcInstance playerA, L2PcInstance playerB, boolean partyDuel, int duelId)
{
_duelId = duelId;
if (partyDuel)
{
_leaderA = playerA;
_leaderB = playerB;
_teamA = new ArrayList<>(playerA.getParty().getMembers());
_teamB = new ArrayList<>(playerB.getParty().getMembers());
}
else
{
_leaderA = playerA;
_leaderB = playerB;
_teamA = new ArrayList<>();
_teamB = new ArrayList<>();
_teamA.add(playerA);
_teamB.add(playerB);
}
_partyDuel = partyDuel;
_duelEndTime = Calendar.getInstance();
_duelEndTime.add(Calendar.SECOND, _partyDuel ? PARTY_DUEL_DURATION : PLAYER_DUEL_DURATION);
savePlayerConditions();
if (_partyDuel)
{
_countdown = PARTY_DUEL_PREPARE_TIME;
teleportPlayers();
}
else
{
_countdown = DUEL_PREPARE_TIME;
}
// Schedule duel start
ThreadPoolManager.getInstance().scheduleGeneral(new DuelPreparationTask(this), _countdown - 3);
}
public static class PlayerCondition
{
private L2PcInstance _player;
private double _hp;
private double _mp;
private double _cp;
private boolean _paDuel;
private int _x, _y, _z;
private Set<Skill> _debuffs;
public PlayerCondition(L2PcInstance player, boolean partyDuel)
{
if (player == null)
{
return;
}
_player = player;
_hp = _player.getCurrentHp();
_mp = _player.getCurrentMp();
_cp = _player.getCurrentCp();
_paDuel = partyDuel;
if (_paDuel)
{
_x = _player.getX();
_y = _player.getY();
_z = _player.getZ();
}
}
public void restoreCondition()
{
if (_player == null)
{
return;
}
_player.setCurrentHp(_hp);
_player.setCurrentMp(_mp);
_player.setCurrentCp(_cp);
_player.setIsInDuel(0);
_player.setTeam(Team.NONE);
_player.broadcastUserInfo();
if (_paDuel)
{
teleportBack();
}
if (_debuffs != null) // Debuff removal
{
for (Skill skill : _debuffs)
{
if (skill != null)
{
_player.stopSkillEffects(true, skill.getId());
}
}
}
}
public void registerDebuff(Skill debuff)
{
if (_debuffs == null)
{
_debuffs = ConcurrentHashMap.newKeySet();
}
_debuffs.add(debuff);
}
public void teleportBack()
{
_player.teleToLocation(_x, _y, _z);
}
public L2PcInstance getPlayer()
{
return _player;
}
}
public static class DuelPreparationTask implements Runnable
{
private final Duel _duel;
public DuelPreparationTask(Duel duel)
{
_duel = duel;
}
@Override
public void run()
{
try
{
if (_duel.countdown() > 0) // duel not started yet - continue countdown
{
ThreadPoolManager.getInstance().scheduleGeneral(this, 1000);
}
else
{
_duel.startDuel();
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "There has been a problem while runing a duel start task!", e);
}
}
}
public class DuelClockTask implements Runnable
{
private final Duel _duel;
public DuelClockTask(Duel duel)
{
_duel = duel;
}
@Override
public void run()
{
try
{
switch (_duel.checkEndDuelCondition())
{
case CONTINUE:
{
ThreadPoolManager.getInstance().scheduleGeneral(this, 1000);
break;
}
default:
{
endDuel();
break;
}
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "There has been a problem while runing a duel end task!", e);
}
}
}
/**
* Starts the duel
*/
public void startDuel()
{
// Set duel state and team
// Send duel packets
broadcastToTeam1(ExDuelReady.PARTY_DUEL);
broadcastToTeam2(ExDuelReady.PARTY_DUEL);
broadcastToTeam1(ExDuelStart.PARTY_DUEL);
broadcastToTeam2(ExDuelStart.PARTY_DUEL);
for (L2PcInstance temp : _teamA)
{
temp.cancelActiveTrade();
temp.setIsInDuel(_duelId);
temp.setTeam(Team.BLUE);
temp.broadcastUserInfo();
broadcastToTeam2(new ExDuelUpdateUserInfo(temp));
}
for (L2PcInstance temp : _teamB)
{
temp.cancelActiveTrade();
temp.setIsInDuel(_duelId);
temp.setTeam(Team.RED);
temp.broadcastUserInfo();
broadcastToTeam1(new ExDuelUpdateUserInfo(temp));
}
if (_partyDuel)
{
// Close doors chickens cannot run from the destiny
for (L2DoorInstance door : InstanceManager.getInstance().getInstance(getDueldInstanceId()).getDoors())
{
if ((door != null) && door.getOpen())
{
door.closeMe();
}
}
}
// play sound
broadcastToTeam1(B04_S01);
broadcastToTeam2(B04_S01);
// start dueling task
ThreadPoolManager.getInstance().scheduleGeneral(new DuelClockTask(this), 1000);
}
/**
* Stops all players from attacking. Used for duel timeout / interrupt.
*/
private void stopFighting()
{
for (L2PcInstance temp : _teamA)
{
temp.abortCast();
temp.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
temp.setTarget(null);
temp.sendPacket(ActionFailed.STATIC_PACKET);
if (temp.hasSummon())
{
for (L2Summon summon : temp.getServitors().values())
{
if (!summon.isDead())
{
summon.abortCast();
summon.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
summon.setTarget(null);
summon.sendPacket(ActionFailed.STATIC_PACKET);
}
}
}
}
for (L2PcInstance temp : _teamB)
{
temp.abortCast();
temp.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
temp.setTarget(null);
temp.sendPacket(ActionFailed.STATIC_PACKET);
if (temp.hasSummon())
{
for (L2Summon summon : temp.getServitors().values())
{
if (!summon.isDead())
{
summon.abortCast();
summon.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
summon.setTarget(null);
summon.sendPacket(ActionFailed.STATIC_PACKET);
}
}
}
}
}
/**
* Save the current player condition: hp, mp, cp, location
*/
public void savePlayerConditions()
{
for (L2PcInstance player : _teamA)
{
_playerConditions.put(player.getObjectId(), new PlayerCondition(player, _partyDuel));
}
for (L2PcInstance player : _teamB)
{
_playerConditions.put(player.getObjectId(), new PlayerCondition(player, _partyDuel));
}
}
/**
* Restore player conditions
*/
public void restorePlayerConditions()
{
// restore player conditions
ThreadPoolManager.getInstance().scheduleGeneral(() ->
{
_playerConditions.values().forEach(c -> c.restoreCondition());
}, _partyDuel ? PARTY_DUEL_TELEPORT_BACK_TIME : 1000);
ThreadPoolManager.getInstance().scheduleGeneral(() -> clear(), _partyDuel ? PARTY_DUEL_TELEPORT_BACK_TIME : 1000);
}
/**
* Get the duel id
* @return id
*/
public int getId()
{
return _duelId;
}
/**
* Get duel instance id
* @return id
*/
public int getDueldInstanceId()
{
return _duelInstanceId;
}
/**
* Returns the remaining time
* @return remaining time
*/
public int getRemainingTime()
{
return (int) (_duelEndTime.getTimeInMillis() - Calendar.getInstance().getTimeInMillis());
}
/**
* Get the team that requested the duel
* @return duel requester
*/
public List<L2PcInstance> getTeamA()
{
return _teamA;
}
/**
* Get the team that was challenged
* @return challenged team
*/
public List<L2PcInstance> getTeamB()
{
return _teamB;
}
/**
* Get the team that requested the duel
* @return duel requester
*/
public L2PcInstance getTeamLeaderA()
{
return _leaderA;
}
/**
* Get the team that was challenged
* @return challenged team
*/
public L2PcInstance getTeamLeaderB()
{
return _leaderB;
}
/**
* Get the duel looser
* @return looser
*/
public List<L2PcInstance> getLooser()
{
if ((_leaderA == null) || (_leaderB == null))
{
return null;
}
if (_leaderA.getDuelState() == DuelState.WINNER)
{
return _teamB;
}
else if (_leaderB.getDuelState() == DuelState.WINNER)
{
return _teamA;
}
return null;
}
/**
* Returns whether this is a party duel or not
* @return is party duel
*/
public boolean isPartyDuel()
{
return _partyDuel;
}
/**
* Teleports all players to a party duel instance.
*/
public void teleportPlayers()
{
if (!_partyDuel)
{
return;
}
_duelInstanceId = InstanceManager.getInstance().createDynamicInstance("PartyDuel.xml");
final Instance instance = InstanceManager.getInstance().getInstance(_duelInstanceId);
int i = 0;
for (L2PcInstance player : _teamA)
{
final Location loc = instance.getEnterLocs().get(i++);
player.teleToLocation(loc.getX(), loc.getY(), loc.getZ(), 0, _duelInstanceId, 0);
}
i = 9;
for (L2PcInstance player : _teamB)
{
final Location loc = instance.getEnterLocs().get(i++);
player.teleToLocation(loc.getX(), loc.getY(), loc.getZ(), 0, _duelInstanceId, 0);
}
}
/**
* Broadcast a packet to the challenger team
* @param packet
*/
public void broadcastToTeam1(L2GameServerPacket packet)
{
if ((_teamA == null) || _teamA.isEmpty())
{
return;
}
for (L2PcInstance temp : _teamA)
{
temp.sendPacket(packet);
}
}
/**
* Broadcast a packet to the challenged team
* @param packet
*/
public void broadcastToTeam2(L2GameServerPacket packet)
{
if ((_teamB == null) || _teamB.isEmpty())
{
return;
}
for (L2PcInstance temp : _teamB)
{
temp.sendPacket(packet);
}
}
/**
* Playback the bow animation for all looser
*/
private void playKneelAnimation()
{
final List<L2PcInstance> looser = getLooser();
if (looser == null)
{
return;
}
for (L2PcInstance temp : looser)
{
temp.broadcastPacket(new SocialAction(temp.getObjectId(), 7));
}
}
/**
* Do the countdown and send message to players if necessary
* @return current count
*/
int countdown()
{
if (--_countdown > 3)
{
return _countdown;
}
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.THE_DUEL_WILL_BEGIN_IN_S1_SECOND_S);
if (_countdown > 0)
{
sm.addInt(_countdown);
}
else
{
sm = SystemMessage.getSystemMessage(SystemMessageId.LET_THE_DUEL_BEGIN);
}
broadcastToTeam1(sm);
broadcastToTeam2(sm);
return _countdown;
}
/**
* The duel has reached a state in which it can no longer continue
*/
void endDuel()
{
// Send end duel packet
final ExDuelEnd duelEnd = _partyDuel ? ExDuelEnd.PARTY_DUEL : ExDuelEnd.PLAYER_DUEL;
broadcastToTeam1(duelEnd);
broadcastToTeam2(duelEnd);
playKneelAnimation();
sendEndMessages();
restorePlayerConditions();
}
/**
* Clear current duel from DuelManager
*/
private void clear()
{
InstanceManager.getInstance().destroyInstance(getDueldInstanceId());
DuelManager.getInstance().removeDuel(this);
}
/**
* Send required messages for duel end
*/
private void sendEndMessages()
{
SystemMessage sm = null;
switch (checkEndDuelCondition())
{
case TEAM_1_WIN:
case TEAM_2_SURRENDER:
{
if (_partyDuel)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_PARTY_HAS_WON_THE_DUEL);
}
else
{
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_WON_THE_DUEL);
}
sm.addString(_leaderA.getName());
break;
}
case TEAM_1_SURRENDER:
case TEAM_2_WIN:
{
if (_partyDuel)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_PARTY_HAS_WON_THE_DUEL);
}
else
{
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_WON_THE_DUEL);
}
break;
}
case CANCELED:
case TIMEOUT:
{
stopFighting();
sm = SystemMessage.getSystemMessage(SystemMessageId.THE_DUEL_HAS_ENDED_IN_A_TIE);
break;
}
}
broadcastToTeam1(sm);
broadcastToTeam2(sm);
}
/**
* Did a situation occur in which the duel has to be ended?
* @return DuelResult duel status
*/
DuelResult checkEndDuelCondition()
{
// one of the players might leave during duel
if ((_teamA == null) || (_teamB == null))
{
return DuelResult.CANCELED;
}
// got a duel surrender request?
if (_surrenderRequest != 0)
{
if (_surrenderRequest == 1)
{
return DuelResult.TEAM_1_SURRENDER;
}
return DuelResult.TEAM_2_SURRENDER;
}
// duel timed out
else if (getRemainingTime() <= 0)
{
return DuelResult.TIMEOUT;
}
// Has a player been declared winner yet?
else if (_leaderA.getDuelState() == DuelState.WINNER)
{
// If there is a Winner already there should be no more fighting going on
stopFighting();
return DuelResult.TEAM_1_WIN;
}
else if (_leaderB.getDuelState() == DuelState.WINNER)
{
// If there is a Winner already there should be no more fighting going on
stopFighting();
return DuelResult.TEAM_2_WIN;
}
// More end duel conditions for 1on1 duels
else if (!_partyDuel)
{
// Duel was interrupted e.g.: player was attacked by mobs / other players
if ((_leaderA.getDuelState() == DuelState.INTERRUPTED) || (_leaderB.getDuelState() == DuelState.INTERRUPTED))
{
return DuelResult.CANCELED;
}
// Are the players too far apart?
if (!_leaderA.isInsideRadius(_leaderB, 2000, false, false))
{
return DuelResult.CANCELED;
}
// is one of the players in a Siege, Peace or PvP zone?
if (_leaderA.isInsideZone(ZoneId.PEACE) || _leaderB.isInsideZone(ZoneId.PEACE) || _leaderA.isInsideZone(ZoneId.SIEGE) || _leaderB.isInsideZone(ZoneId.SIEGE) || _leaderA.isInsideZone(ZoneId.PVP) || _leaderB.isInsideZone(ZoneId.PVP))
{
return DuelResult.CANCELED;
}
}
return DuelResult.CONTINUE;
}
/**
* Register a surrender request
* @param player the player that surrenders.
*/
public void doSurrender(L2PcInstance player)
{
// already received a surrender request
if ((_surrenderRequest != 0) || _partyDuel)
{
return;
}
// stop the fight
stopFighting();
if (player == _leaderA)
{
_surrenderRequest = 1;
_leaderA.setDuelState(DuelState.DEAD);
_leaderB.setDuelState(DuelState.WINNER);
}
else if (player == _leaderB)
{
_surrenderRequest = 2;
_leaderB.setDuelState(DuelState.DEAD);
_leaderA.setDuelState(DuelState.WINNER);
}
}
/**
* This function is called whenever a player was defeated in a duel
* @param player the player defeated.
*/
public void onPlayerDefeat(L2PcInstance player)
{
// Set player as defeated
player.setDuelState(DuelState.DEAD);
player.setTeam(Team.NONE);
if (_partyDuel)
{
boolean teamdefeated = true;
boolean isInTeamA = true;
if (_teamA.contains(player))
{
for (L2PcInstance temp : _teamA)
{
if (temp.getDuelState() == DuelState.DUELLING)
{
teamdefeated = false;
break;
}
}
}
else if (_teamB.contains(player))
{
isInTeamA = false;
for (L2PcInstance temp : _teamB)
{
if (temp.getDuelState() == DuelState.DUELLING)
{
teamdefeated = false;
break;
}
}
}
if (teamdefeated)
{
final List<L2PcInstance> winners = (isInTeamA ? _teamB : _teamA);
for (L2PcInstance temp : winners)
{
temp.setDuelState(DuelState.WINNER);
}
}
}
else
{
if ((player != _leaderA) && (player != _leaderB))
{
_log.warning("Error in onPlayerDefeat(): player is not part of this 1vs1 duel!");
}
if (_leaderA == player)
{
_leaderB.setDuelState(DuelState.WINNER);
}
else
{
_leaderA.setDuelState(DuelState.WINNER);
}
}
}
public void onBuff(L2PcInstance player, Skill debuff)
{
final PlayerCondition cond = _playerConditions.get(player.getObjectId());
if (cond != null)
{
cond.registerDebuff(debuff);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,177 @@
/*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
/**
* @author Erlandys
*/
public class Friend
{
int _relation;
int _friendOID;
String _memo;
int _level = 1;
int _classId = 0;
int _clanId = 0;
int _clanCrestId = 0;
int _allyId = 0;
int _allyCrestId = 0;
String _name = "";
String _clanName = "";
String _allyName = "";
long _createDate = -1;
long _lastLogin = -1;
public Friend(int relation, int friendOID, String memo)
{
_relation = relation;
_friendOID = friendOID;
_memo = memo;
}
public L2PcInstance getFriend()
{
return L2World.getInstance().getPlayer(_friendOID);
}
public int getFriendOID()
{
return _friendOID;
}
public String getMemo()
{
return _memo;
}
public void setMemo(String memo)
{
_memo = memo;
}
public int getLevel()
{
return _level;
}
public void setLevel(int level)
{
_level = level;
}
public int getClassId()
{
return _classId;
}
public void setClassId(int classId)
{
_classId = classId;
}
public int getClanId()
{
return _clanId;
}
public void setClanId(int clanId)
{
_clanId = clanId;
}
public int getClanCrestId()
{
return _clanCrestId;
}
public void setClanCrestId(int clanCrestId)
{
_clanCrestId = clanCrestId;
}
public int getAllyId()
{
return _allyId;
}
public void setAllyId(int allyId)
{
_allyId = allyId;
}
public int getAllyCrestId()
{
return _allyCrestId;
}
public void setAllyCrestId(int allyCrestId)
{
_allyCrestId = allyCrestId;
}
public String getName()
{
if (_name == "")
{
_name = CharNameTable.getInstance().getNameById(_friendOID);
}
return _name;
}
public String getClanName()
{
return _clanName;
}
public void setClanName(String clanName)
{
_clanName = clanName;
}
public String getAllyName()
{
return _allyName;
}
public void setAllyName(String allyName)
{
_allyName = allyName;
}
public long getCreateDate()
{
return _createDate;
}
public void setCreateDate(long createDate)
{
_createDate = createDate;
}
public long getLastLogin()
{
return _lastLogin;
}
public void setLastLogin(long lastLogin)
{
_lastLogin = lastLogin;
}
}

View File

@ -0,0 +1,964 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.pool.impl.ConnectionFactory;
import com.l2jmobius.gameserver.cache.HtmCache;
import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.data.xml.impl.ClassListData;
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
import com.l2jmobius.gameserver.instancemanager.CastleManager;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.olympiad.Olympiad;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.SocialAction;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
import com.l2jmobius.util.StringUtil;
/**
* Hero entity.
* @author godson
*/
public class Hero
{
private static final Logger _log = Logger.getLogger(Hero.class.getName());
private static final String GET_HEROES = "SELECT heroes.charId, characters.char_name, heroes.class_id, heroes.count, heroes.played, heroes.claimed FROM heroes, characters WHERE characters.charId = heroes.charId AND heroes.played = 1";
private static final String GET_ALL_HEROES = "SELECT heroes.charId, characters.char_name, heroes.class_id, heroes.count, heroes.played, heroes.claimed FROM heroes, characters WHERE characters.charId = heroes.charId";
private static final String UPDATE_ALL = "UPDATE heroes SET played = 0";
private static final String INSERT_HERO = "INSERT INTO heroes (charId, class_id, count, played, claimed) VALUES (?,?,?,?,?)";
private static final String UPDATE_HERO = "UPDATE heroes SET count = ?, played = ?, claimed = ? WHERE charId = ?";
private static final String GET_CLAN_ALLY = "SELECT characters.clanid AS clanid, coalesce(clan_data.ally_Id, 0) AS allyId FROM characters LEFT JOIN clan_data ON clan_data.clan_id = characters.clanid WHERE characters.charId = ?";
// delete hero items
private static final String DELETE_ITEMS = "DELETE FROM items WHERE item_id IN (6842, 6611, 6612, 6613, 6614, 6615, 6616, 6617, 6618, 6619, 6620, 6621, 9388, 9389, 9390) AND owner_id NOT IN (SELECT charId FROM characters WHERE accesslevel > 0)";
private static final Map<Integer, StatsSet> HEROES = new ConcurrentHashMap<>();
private static final Map<Integer, StatsSet> COMPLETE_HEROS = new ConcurrentHashMap<>();
private static final Map<Integer, StatsSet> HERO_COUNTS = new ConcurrentHashMap<>();
private static final Map<Integer, List<StatsSet>> HERO_FIGHTS = new ConcurrentHashMap<>();
private static final Map<Integer, List<StatsSet>> HERO_DIARY = new ConcurrentHashMap<>();
private static final Map<Integer, String> HERO_MESSAGE = new ConcurrentHashMap<>();
public static final String COUNT = "count";
public static final String PLAYED = "played";
public static final String CLAIMED = "claimed";
public static final String CLAN_NAME = "clan_name";
public static final String CLAN_CREST = "clan_crest";
public static final String ALLY_NAME = "ally_name";
public static final String ALLY_CREST = "ally_crest";
public static final int ACTION_RAID_KILLED = 1;
public static final int ACTION_HERO_GAINED = 2;
public static final int ACTION_CASTLE_TAKEN = 3;
protected Hero()
{
init();
}
private void init()
{
HEROES.clear();
COMPLETE_HEROS.clear();
HERO_COUNTS.clear();
HERO_FIGHTS.clear();
HERO_DIARY.clear();
HERO_MESSAGE.clear();
try (Connection con = ConnectionFactory.getInstance().getConnection();
Statement s1 = con.createStatement();
ResultSet rset = s1.executeQuery(GET_HEROES);
PreparedStatement ps = con.prepareStatement(GET_CLAN_ALLY);
Statement s2 = con.createStatement();
ResultSet rset2 = s2.executeQuery(GET_ALL_HEROES))
{
while (rset.next())
{
final StatsSet hero = new StatsSet();
final int charId = rset.getInt(Olympiad.CHAR_ID);
hero.set(Olympiad.CHAR_NAME, rset.getString(Olympiad.CHAR_NAME));
hero.set(Olympiad.CLASS_ID, rset.getInt(Olympiad.CLASS_ID));
hero.set(COUNT, rset.getInt(COUNT));
hero.set(PLAYED, rset.getInt(PLAYED));
hero.set(CLAIMED, Boolean.parseBoolean(rset.getString(CLAIMED)));
loadFights(charId);
loadDiary(charId);
loadMessage(charId);
processHeros(ps, charId, hero);
HEROES.put(charId, hero);
}
while (rset2.next())
{
final StatsSet hero = new StatsSet();
final int charId = rset2.getInt(Olympiad.CHAR_ID);
hero.set(Olympiad.CHAR_NAME, rset2.getString(Olympiad.CHAR_NAME));
hero.set(Olympiad.CLASS_ID, rset2.getInt(Olympiad.CLASS_ID));
hero.set(COUNT, rset2.getInt(COUNT));
hero.set(PLAYED, rset2.getInt(PLAYED));
hero.set(CLAIMED, Boolean.parseBoolean(rset2.getString(CLAIMED)));
processHeros(ps, charId, hero);
COMPLETE_HEROS.put(charId, hero);
}
}
catch (SQLException e)
{
_log.warning("Hero System: Couldnt load Heroes: " + e.getMessage());
}
_log.info("Hero System: Loaded " + HEROES.size() + " Heroes.");
_log.info("Hero System: Loaded " + COMPLETE_HEROS.size() + " all time Heroes.");
}
private void processHeros(PreparedStatement ps, int charId, StatsSet hero) throws SQLException
{
ps.setInt(1, charId);
try (ResultSet rs = ps.executeQuery())
{
if (rs.next())
{
final int clanId = rs.getInt("clanid");
final int allyId = rs.getInt("allyId");
String clanName = "";
String allyName = "";
int clanCrest = 0;
int allyCrest = 0;
if (clanId > 0)
{
clanName = ClanTable.getInstance().getClan(clanId).getName();
clanCrest = ClanTable.getInstance().getClan(clanId).getCrestId();
if (allyId > 0)
{
allyName = ClanTable.getInstance().getClan(clanId).getAllyName();
allyCrest = ClanTable.getInstance().getClan(clanId).getAllyCrestId();
}
}
hero.set(CLAN_CREST, clanCrest);
hero.set(CLAN_NAME, clanName);
hero.set(ALLY_CREST, allyCrest);
hero.set(ALLY_NAME, allyName);
}
ps.clearParameters();
}
}
private String calcFightTime(long FightTime)
{
final String format = String.format("%%0%dd", 2);
FightTime = FightTime / 1000;
final String seconds = String.format(format, FightTime % 60);
final String minutes = String.format(format, (FightTime % 3600) / 60);
final String time = minutes + ":" + seconds;
return time;
}
/**
* Restore hero message from Db.
* @param charId
*/
public void loadMessage(int charId)
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT message FROM heroes WHERE charId=?"))
{
ps.setInt(1, charId);
try (ResultSet rset = ps.executeQuery())
{
if (rset.next())
{
HERO_MESSAGE.put(charId, rset.getString("message"));
}
}
}
catch (SQLException e)
{
_log.warning("Hero System: Couldnt load Hero Message for CharId: " + charId + ": " + e.getMessage());
}
}
public void loadDiary(int charId)
{
final List<StatsSet> diary = new ArrayList<>();
int diaryentries = 0;
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT * FROM heroes_diary WHERE charId=? ORDER BY time ASC"))
{
ps.setInt(1, charId);
try (ResultSet rset = ps.executeQuery())
{
while (rset.next())
{
final StatsSet _diaryentry = new StatsSet();
final long time = rset.getLong("time");
final int action = rset.getInt("action");
final int param = rset.getInt("param");
final String date = (new SimpleDateFormat("yyyy-MM-dd HH")).format(new Date(time));
_diaryentry.set("date", date);
if (action == ACTION_RAID_KILLED)
{
final L2NpcTemplate template = NpcData.getInstance().getTemplate(param);
if (template != null)
{
_diaryentry.set("action", template.getName() + " was defeated");
}
}
else if (action == ACTION_HERO_GAINED)
{
_diaryentry.set("action", "Gained Hero status");
}
else if (action == ACTION_CASTLE_TAKEN)
{
final Castle castle = CastleManager.getInstance().getCastleById(param);
if (castle != null)
{
_diaryentry.set("action", castle.getName() + " Castle was successfuly taken");
}
}
diary.add(_diaryentry);
diaryentries++;
}
}
HERO_DIARY.put(charId, diary);
_log.info("Hero System: Loaded " + diaryentries + " diary entries for Hero: " + CharNameTable.getInstance().getNameById(charId));
}
catch (SQLException e)
{
_log.warning("Hero System: Couldnt load Hero Diary for CharId: " + charId + ": " + e.getMessage());
}
}
public void loadFights(int charId)
{
final List<StatsSet> fights = new ArrayList<>();
final StatsSet heroCountData = new StatsSet();
final Calendar data = Calendar.getInstance();
data.set(Calendar.DAY_OF_MONTH, 1);
data.set(Calendar.HOUR_OF_DAY, 0);
data.set(Calendar.MINUTE, 0);
data.set(Calendar.MILLISECOND, 0);
final long from = data.getTimeInMillis();
int numberoffights = 0;
int _victorys = 0;
int _losses = 0;
int _draws = 0;
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT * FROM olympiad_fights WHERE (charOneId=? OR charTwoId=?) AND start<? ORDER BY start ASC"))
{
ps.setInt(1, charId);
ps.setInt(2, charId);
ps.setLong(3, from);
try (ResultSet rset = ps.executeQuery())
{
int charOneId;
int charOneClass;
int charTwoId;
int charTwoClass;
int winner;
long start;
long time;
int classed;
while (rset.next())
{
charOneId = rset.getInt("charOneId");
charOneClass = rset.getInt("charOneClass");
charTwoId = rset.getInt("charTwoId");
charTwoClass = rset.getInt("charTwoClass");
winner = rset.getInt("winner");
start = rset.getLong("start");
time = rset.getLong("time");
classed = rset.getInt("classed");
if (charId == charOneId)
{
final String name = CharNameTable.getInstance().getNameById(charTwoId);
final String cls = ClassListData.getInstance().getClass(charTwoClass).getClientCode();
if ((name != null) && (cls != null))
{
final StatsSet fight = new StatsSet();
fight.set("oponent", name);
fight.set("oponentclass", cls);
fight.set("time", calcFightTime(time));
final String date = (new SimpleDateFormat("yyyy-MM-dd HH:mm")).format(new Date(start));
fight.set("start", date);
fight.set("classed", classed);
if (winner == 1)
{
fight.set("result", "<font color=\"00ff00\">victory</font>");
_victorys++;
}
else if (winner == 2)
{
fight.set("result", "<font color=\"ff0000\">loss</font>");
_losses++;
}
else if (winner == 0)
{
fight.set("result", "<font color=\"ffff00\">draw</font>");
_draws++;
}
fights.add(fight);
numberoffights++;
}
}
else if (charId == charTwoId)
{
final String name = CharNameTable.getInstance().getNameById(charOneId);
final String cls = ClassListData.getInstance().getClass(charOneClass).getClientCode();
if ((name != null) && (cls != null))
{
final StatsSet fight = new StatsSet();
fight.set("oponent", name);
fight.set("oponentclass", cls);
fight.set("time", calcFightTime(time));
final String date = (new SimpleDateFormat("yyyy-MM-dd HH:mm")).format(new Date(start));
fight.set("start", date);
fight.set("classed", classed);
if (winner == 1)
{
fight.set("result", "<font color=\"ff0000\">loss</font>");
_losses++;
}
else if (winner == 2)
{
fight.set("result", "<font color=\"00ff00\">victory</font>");
_victorys++;
}
else if (winner == 0)
{
fight.set("result", "<font color=\"ffff00\">draw</font>");
_draws++;
}
fights.add(fight);
numberoffights++;
}
}
}
}
heroCountData.set("victory", _victorys);
heroCountData.set("draw", _draws);
heroCountData.set("loss", _losses);
HERO_COUNTS.put(charId, heroCountData);
HERO_FIGHTS.put(charId, fights);
_log.info("Hero System: Loaded " + numberoffights + " fights for Hero: " + CharNameTable.getInstance().getNameById(charId));
}
catch (SQLException e)
{
_log.warning("Hero System: Couldnt load Hero fights history for CharId: " + charId + ": " + e);
}
}
public Map<Integer, StatsSet> getHeroes()
{
return HEROES;
}
public int getHeroByClass(int classid)
{
for (Entry<Integer, StatsSet> e : HEROES.entrySet())
{
if (e.getValue().getInt(Olympiad.CLASS_ID) == classid)
{
return e.getKey();
}
}
return 0;
}
public void resetData()
{
HERO_DIARY.clear();
HERO_FIGHTS.clear();
HERO_COUNTS.clear();
HERO_MESSAGE.clear();
}
public void showHeroDiary(L2PcInstance activeChar, int heroclass, int charid, int page)
{
final int perpage = 10;
final List<StatsSet> mainList = HERO_DIARY.get(charid);
if (mainList != null)
{
final NpcHtmlMessage diaryReply = new NpcHtmlMessage();
final String htmContent = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "html/olympiad/herodiary.htm");
final String heroMessage = HERO_MESSAGE.get(charid);
if ((htmContent != null) && (heroMessage != null))
{
diaryReply.setHtml(htmContent);
diaryReply.replace("%heroname%", CharNameTable.getInstance().getNameById(charid));
diaryReply.replace("%message%", heroMessage);
diaryReply.disableValidation();
if (!mainList.isEmpty())
{
final List<StatsSet> list = new ArrayList<>(mainList);
Collections.reverse(list);
boolean color = true;
final StringBuilder fList = new StringBuilder(500);
int counter = 0;
int breakat = 0;
for (int i = ((page - 1) * perpage); i < list.size(); i++)
{
breakat = i;
final StatsSet diaryEntry = list.get(i);
StringUtil.append(fList, "<tr><td>");
if (color)
{
StringUtil.append(fList, "<table width=270 bgcolor=\"131210\">");
}
else
{
StringUtil.append(fList, "<table width=270>");
}
StringUtil.append(fList, "<tr><td width=270><font color=\"LEVEL\">" + diaryEntry.getString("date") + ":xx</font></td></tr>");
StringUtil.append(fList, "<tr><td width=270>" + diaryEntry.getString("action") + "</td></tr>");
StringUtil.append(fList, "<tr><td>&nbsp;</td></tr></table>");
StringUtil.append(fList, "</td></tr>");
color = !color;
counter++;
if (counter >= perpage)
{
break;
}
}
if (breakat < (list.size() - 1))
{
diaryReply.replace("%buttprev%", "<button value=\"Prev\" action=\"bypass _diary?class=" + heroclass + "&page=" + (page + 1) + "\" width=60 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
}
else
{
diaryReply.replace("%buttprev%", "");
}
if (page > 1)
{
diaryReply.replace("%buttnext%", "<button value=\"Next\" action=\"bypass _diary?class=" + heroclass + "&page=" + (page - 1) + "\" width=60 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
}
else
{
diaryReply.replace("%buttnext%", "");
}
diaryReply.replace("%list%", fList.toString());
}
else
{
diaryReply.replace("%list%", "");
diaryReply.replace("%buttprev%", "");
diaryReply.replace("%buttnext%", "");
}
activeChar.sendPacket(diaryReply);
}
}
}
public void showHeroFights(L2PcInstance activeChar, int heroclass, int charid, int page)
{
final int perpage = 20;
int _win = 0;
int _loss = 0;
int _draw = 0;
final List<StatsSet> heroFights = HERO_FIGHTS.get(charid);
if (heroFights != null)
{
final NpcHtmlMessage FightReply = new NpcHtmlMessage();
final String htmContent = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "html/olympiad/herohistory.htm");
if (htmContent != null)
{
FightReply.setHtml(htmContent);
FightReply.replace("%heroname%", CharNameTable.getInstance().getNameById(charid));
if (!heroFights.isEmpty())
{
final StatsSet heroCount = HERO_COUNTS.get(charid);
if (heroCount != null)
{
_win = heroCount.getInt("victory");
_loss = heroCount.getInt("loss");
_draw = heroCount.getInt("draw");
}
boolean color = true;
final StringBuilder fList = new StringBuilder(500);
int counter = 0;
int breakat = 0;
for (int i = ((page - 1) * perpage); i < heroFights.size(); i++)
{
breakat = i;
final StatsSet fight = heroFights.get(i);
StringUtil.append(fList, "<tr><td>");
if (color)
{
StringUtil.append(fList, "<table width=270 bgcolor=\"131210\">");
}
else
{
StringUtil.append(fList, "<table width=270>");
}
StringUtil.append(fList, "<tr><td width=220><font color=\"LEVEL\">" + fight.getString("start") + "</font>&nbsp;&nbsp;" + fight.getString("result") + "</td><td width=50 align=right>" + (fight.getInt("classed") > 0 ? "<font color=\"FFFF99\">cls</font>" : "<font color=\"999999\">non-cls<font>") + "</td></tr>");
StringUtil.append(fList, "<tr><td width=220>vs " + fight.getString("oponent") + " (" + fight.getString("oponentclass") + ")</td><td width=50 align=right>(" + fight.getString("time") + ")</td></tr>");
StringUtil.append(fList, "<tr><td colspan=2>&nbsp;</td></tr></table>");
StringUtil.append(fList, "</td></tr>");
color = !color;
counter++;
if (counter >= perpage)
{
break;
}
}
if (breakat < (heroFights.size() - 1))
{
FightReply.replace("%buttprev%", "<button value=\"Prev\" action=\"bypass _match?class=" + heroclass + "&page=" + (page + 1) + "\" width=60 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
}
else
{
FightReply.replace("%buttprev%", "");
}
if (page > 1)
{
FightReply.replace("%buttnext%", "<button value=\"Next\" action=\"bypass _match?class=" + heroclass + "&page=" + (page - 1) + "\" width=60 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
}
else
{
FightReply.replace("%buttnext%", "");
}
FightReply.replace("%list%", fList.toString());
}
else
{
FightReply.replace("%list%", "");
FightReply.replace("%buttprev%", "");
FightReply.replace("%buttnext%", "");
}
FightReply.replace("%win%", String.valueOf(_win));
FightReply.replace("%draw%", String.valueOf(_draw));
FightReply.replace("%loos%", String.valueOf(_loss));
activeChar.sendPacket(FightReply);
}
}
}
public synchronized void computeNewHeroes(List<StatsSet> newHeroes)
{
updateHeroes(true);
for (Integer objectId : HEROES.keySet())
{
final L2PcInstance player = L2World.getInstance().getPlayer(objectId);
if (player == null)
{
continue;
}
player.setHero(false);
for (int i = 0; i < Inventory.PAPERDOLL_TOTALSLOTS; i++)
{
final L2ItemInstance equippedItem = player.getInventory().getPaperdollItem(i);
if ((equippedItem != null) && equippedItem.isHeroItem())
{
player.getInventory().unEquipItemInSlot(i);
}
}
final InventoryUpdate iu = new InventoryUpdate();
for (L2ItemInstance item : player.getInventory().getItems())
{
if ((item != null) && item.isHeroItem())
{
player.destroyItem("Hero", item, null, true);
iu.addRemovedItem(item);
}
}
if (!iu.getItems().isEmpty())
{
player.sendPacket(iu);
}
player.broadcastUserInfo();
}
deleteItemsInDb();
HEROES.clear();
if (newHeroes.isEmpty())
{
return;
}
for (StatsSet hero : newHeroes)
{
final int charId = hero.getInt(Olympiad.CHAR_ID);
if (COMPLETE_HEROS.containsKey(charId))
{
final StatsSet oldHero = COMPLETE_HEROS.get(charId);
final int count = oldHero.getInt(COUNT);
oldHero.set(COUNT, count + 1);
oldHero.set(PLAYED, 1);
oldHero.set(CLAIMED, false);
HEROES.put(charId, oldHero);
}
else
{
final StatsSet newHero = new StatsSet();
newHero.set(Olympiad.CHAR_NAME, hero.getString(Olympiad.CHAR_NAME));
newHero.set(Olympiad.CLASS_ID, hero.getInt(Olympiad.CLASS_ID));
newHero.set(COUNT, 1);
newHero.set(PLAYED, 1);
newHero.set(CLAIMED, false);
HEROES.put(charId, newHero);
}
}
updateHeroes(false);
}
public void updateHeroes(boolean setDefault)
{
try (Connection con = ConnectionFactory.getInstance().getConnection())
{
if (setDefault)
{
try (Statement s = con.createStatement())
{
s.executeUpdate(UPDATE_ALL);
}
}
else
{
StatsSet hero;
int heroId;
for (Entry<Integer, StatsSet> entry : HEROES.entrySet())
{
hero = entry.getValue();
heroId = entry.getKey();
if (!COMPLETE_HEROS.containsKey(heroId))
{
try (PreparedStatement insert = con.prepareStatement(INSERT_HERO))
{
insert.setInt(1, heroId);
insert.setInt(2, hero.getInt(Olympiad.CLASS_ID));
insert.setInt(3, hero.getInt(COUNT));
insert.setInt(4, hero.getInt(PLAYED));
insert.setString(5, String.valueOf(hero.getBoolean(CLAIMED)));
insert.execute();
insert.close();
}
try (PreparedStatement statement = con.prepareStatement(GET_CLAN_ALLY))
{
statement.setInt(1, heroId);
try (ResultSet rset = statement.executeQuery())
{
if (rset.next())
{
final int clanId = rset.getInt("clanid");
final int allyId = rset.getInt("allyId");
String clanName = "";
String allyName = "";
int clanCrest = 0;
int allyCrest = 0;
if (clanId > 0)
{
clanName = ClanTable.getInstance().getClan(clanId).getName();
clanCrest = ClanTable.getInstance().getClan(clanId).getCrestId();
if (allyId > 0)
{
allyName = ClanTable.getInstance().getClan(clanId).getAllyName();
allyCrest = ClanTable.getInstance().getClan(clanId).getAllyCrestId();
}
}
hero.set(CLAN_CREST, clanCrest);
hero.set(CLAN_NAME, clanName);
hero.set(ALLY_CREST, allyCrest);
hero.set(ALLY_NAME, allyName);
}
}
}
HEROES.put(heroId, hero);
COMPLETE_HEROS.put(heroId, hero);
}
else
{
try (PreparedStatement statement = con.prepareStatement(UPDATE_HERO))
{
statement.setInt(1, hero.getInt(COUNT));
statement.setInt(2, hero.getInt(PLAYED));
statement.setString(3, String.valueOf(hero.getBoolean(CLAIMED)));
statement.setInt(4, heroId);
statement.execute();
}
}
}
}
}
catch (SQLException e)
{
_log.warning("Hero System: Couldnt update Heroes: " + e.getMessage());
}
}
public void setHeroGained(int charId)
{
setDiaryData(charId, ACTION_HERO_GAINED, 0);
}
public void setRBkilled(int charId, int npcId)
{
setDiaryData(charId, ACTION_RAID_KILLED, npcId);
final L2NpcTemplate template = NpcData.getInstance().getTemplate(npcId);
final List<StatsSet> list = HERO_DIARY.get(charId);
if ((list != null) && (template != null))
{
// Prepare new data
final StatsSet diaryEntry = new StatsSet();
final String date = (new SimpleDateFormat("yyyy-MM-dd HH")).format(new Date(System.currentTimeMillis()));
diaryEntry.set("date", date);
diaryEntry.set("action", template.getName() + " was defeated");
// Add to old list
list.add(diaryEntry);
}
}
public void setCastleTaken(int charId, int castleId)
{
setDiaryData(charId, ACTION_CASTLE_TAKEN, castleId);
final Castle castle = CastleManager.getInstance().getCastleById(castleId);
final List<StatsSet> list = HERO_DIARY.get(charId);
if ((list != null) && (castle != null))
{
// Prepare new data
final StatsSet diaryEntry = new StatsSet();
final String date = (new SimpleDateFormat("yyyy-MM-dd HH")).format(new Date(System.currentTimeMillis()));
diaryEntry.set("date", date);
diaryEntry.set("action", castle.getName() + " Castle was successfuly taken");
// Add to old list
list.add(diaryEntry);
}
}
public void setDiaryData(int charId, int action, int param)
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("INSERT INTO heroes_diary (charId, time, action, param) values(?,?,?,?)"))
{
ps.setInt(1, charId);
ps.setLong(2, System.currentTimeMillis());
ps.setInt(3, action);
ps.setInt(4, param);
ps.execute();
}
catch (SQLException e)
{
_log.severe("SQL exception while saving DiaryData: " + e.getMessage());
}
}
/**
* Set new hero message for hero
* @param player the player instance
* @param message String to set
*/
public void setHeroMessage(L2PcInstance player, String message)
{
HERO_MESSAGE.put(player.getObjectId(), message);
}
/**
* Update hero message in database
* @param charId character objid
*/
public void saveHeroMessage(int charId)
{
if (HERO_MESSAGE.containsKey(charId))
{
return;
}
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("UPDATE heroes SET message=? WHERE charId=?;"))
{
ps.setString(1, HERO_MESSAGE.get(charId));
ps.setInt(2, charId);
ps.execute();
}
catch (SQLException e)
{
_log.severe("SQL exception while saving HeroMessage:" + e.getMessage());
}
}
private void deleteItemsInDb()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
Statement s = con.createStatement())
{
s.executeUpdate(DELETE_ITEMS);
}
catch (SQLException e)
{
_log.warning("Heroes: " + e.getMessage());
}
}
/**
* Saving task for {@link Hero}<BR>
* Save all hero messages to DB.
*/
public void shutdown()
{
HERO_MESSAGE.keySet().forEach(c -> saveHeroMessage(c));
}
/**
* Verifies if the given object ID belongs to a claimed hero.
* @param objectId the player's object ID to verify
* @return {@code true} if there are heros and the player is in the list, {@code false} otherwise
*/
public boolean isHero(int objectId)
{
return HEROES.containsKey(objectId) && HEROES.get(objectId).getBoolean(CLAIMED);
}
/**
* Verifies if the given object ID belongs to an unclaimed hero.
* @param objectId the player's object ID to verify
* @return {@code true} if player is unclaimed hero
*/
public boolean isUnclaimedHero(int objectId)
{
return HEROES.containsKey(objectId) && !HEROES.get(objectId).getBoolean(CLAIMED);
}
/**
* Claims the hero status for the given player.
* @param player the player to become hero
*/
public void claimHero(L2PcInstance player)
{
StatsSet hero = HEROES.get(player.getObjectId());
if (hero == null)
{
hero = new StatsSet();
HEROES.put(player.getObjectId(), hero);
}
hero.set(CLAIMED, true);
final L2Clan clan = player.getClan();
if ((clan != null) && (clan.getLevel() >= 5))
{
clan.addReputationScore(Config.HERO_POINTS, true);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.CLAN_MEMBER_C1_WAS_NAMED_A_HERO_S2_POINTS_HAVE_BEEN_ADDED_TO_YOUR_CLAN_REPUTATION);
sm.addString(CharNameTable.getInstance().getNameById(player.getObjectId()));
sm.addInt(Config.HERO_POINTS);
clan.broadcastToOnlineMembers(sm);
}
player.setHero(true);
player.broadcastPacket(new SocialAction(player.getObjectId(), 20016)); // Hero Animation
player.sendPacket(new UserInfo(player));
player.broadcastUserInfo();
// Set Gained hero and reload data
setHeroGained(player.getObjectId());
loadFights(player.getObjectId());
loadDiary(player.getObjectId());
HERO_MESSAGE.put(player.getObjectId(), "");
updateHeroes(false);
}
public static Hero getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final Hero INSTANCE = new Hero();
}
}

View File

@ -0,0 +1,993 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.io.File;
import java.io.IOException;
import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.enums.InstanceReenterType;
import com.l2jmobius.gameserver.enums.InstanceRemoveBuffType;
import com.l2jmobius.gameserver.instancemanager.InstanceManager;
import com.l2jmobius.gameserver.model.L2Spawn;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.L2WorldRegion;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.TeleportWhereType;
import com.l2jmobius.gameserver.model.actor.L2Attackable;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2DoorTemplate;
import com.l2jmobius.gameserver.model.holders.InstanceReenterTimeHolder;
import com.l2jmobius.gameserver.model.instancezone.InstanceWorld;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.util.Broadcast;
/**
* Main class for game instances.
* @author evill33t, GodKratos
*/
public final class Instance
{
private static final Logger _log = Logger.getLogger(Instance.class.getName());
private final int _id;
private String _name;
private int _ejectTime = Config.EJECT_DEAD_PLAYER_TIME;
/** Allow random walk for NPCs, global parameter. */
private boolean _allowRandomWalk = true;
private final List<Integer> _players = new CopyOnWriteArrayList<>();
private final List<L2Npc> _npcs = new CopyOnWriteArrayList<>();
private final Map<Integer, L2DoorInstance> _doors = new ConcurrentHashMap<>();
private final Map<String, List<L2Spawn>> _manualSpawn = new HashMap<>();
// private StartPosType _enterLocationOrder; TODO implement me
private List<Location> _enterLocations = null;
private Location _exitLocation = null;
private boolean _allowSummon = true;
private long _emptyDestroyTime = -1;
private long _lastLeft = -1;
private long _instanceStartTime = -1;
private long _instanceEndTime = -1;
private boolean _isPvPInstance = false;
private boolean _showTimer = false;
private boolean _isTimerIncrease = true;
private String _timerText = "";
// Instance reset data
private InstanceReenterType _type = InstanceReenterType.NONE;
private final List<InstanceReenterTimeHolder> _resetData = new ArrayList<>();
// Instance remove buffs data
private InstanceRemoveBuffType _removeBuffType = InstanceRemoveBuffType.NONE;
private final List<Integer> _exceptionList = new ArrayList<>();
protected ScheduledFuture<?> _checkTimeUpTask = null;
protected final Map<Integer, ScheduledFuture<?>> _ejectDeadTasks = new ConcurrentHashMap<>();
public Instance(int id)
{
_id = id;
_instanceStartTime = System.currentTimeMillis();
}
public Instance(int id, String name)
{
_id = id;
_name = name;
_instanceStartTime = System.currentTimeMillis();
}
/**
* @return the ID of this instance.
*/
public int getId()
{
return _id;
}
/**
* @return the name of this instance
*/
public String getName()
{
return _name;
}
public void setName(String name)
{
_name = name;
}
/**
* @return the eject time
*/
public int getEjectTime()
{
return _ejectTime;
}
/**
* @param ejectTime the player eject time upon death
*/
public void setEjectTime(int ejectTime)
{
_ejectTime = ejectTime;
}
/**
* @return whether summon friend type skills are allowed for this instance
*/
public boolean isSummonAllowed()
{
return _allowSummon;
}
/**
* Sets the status for the instance for summon friend type skills
* @param b
*/
public void setAllowSummon(boolean b)
{
_allowSummon = b;
}
/**
* Returns true if entire instance is PvP zone
* @return
*/
public boolean isPvPInstance()
{
return _isPvPInstance;
}
/**
* Sets PvP zone status of the instance
* @param b
*/
public void setPvPInstance(boolean b)
{
_isPvPInstance = b;
}
/**
* Set the instance duration task
* @param duration in milliseconds
*/
public void setDuration(int duration)
{
if (_checkTimeUpTask != null)
{
_checkTimeUpTask.cancel(true);
}
_checkTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(duration), 500);
_instanceEndTime = System.currentTimeMillis() + duration + 500;
}
/**
* Set time before empty instance will be removed
* @param time in milliseconds
*/
public void setEmptyDestroyTime(long time)
{
_emptyDestroyTime = time;
}
/**
* Checks if the player exists within this instance
* @param objectId
* @return true if player exists in instance
*/
public boolean containsPlayer(int objectId)
{
return _players.contains(objectId);
}
/**
* Adds the specified player to the instance
* @param objectId Players object ID
*/
public void addPlayer(int objectId)
{
_players.add(objectId);
}
/**
* Removes the specified player from the instance list.
* @param objectId the player's object Id
*/
public void removePlayer(Integer objectId)
{
_players.remove(objectId);
if (_players.isEmpty() && (_emptyDestroyTime >= 0))
{
_lastLeft = System.currentTimeMillis();
setDuration((int) (_instanceEndTime - System.currentTimeMillis() - 500));
}
}
public void addNpc(L2Npc npc)
{
_npcs.add(npc);
}
public void removeNpc(L2Npc npc)
{
if (npc.getSpawn() != null)
{
npc.getSpawn().stopRespawn();
}
_npcs.remove(npc);
}
/**
* Adds a door into the instance
* @param doorId - from doors.xml
* @param set - StatsSet for initializing door
*/
public void addDoor(int doorId, StatsSet set)
{
if (_doors.containsKey(doorId))
{
_log.warning("Door ID " + doorId + " already exists in instance " + getId());
return;
}
final L2DoorInstance newdoor = new L2DoorInstance(new L2DoorTemplate(set));
newdoor.setInstanceId(getId());
newdoor.setCurrentHp(newdoor.getMaxHp());
newdoor.spawnMe(newdoor.getTemplate().getX(), newdoor.getTemplate().getY(), newdoor.getTemplate().getZ());
_doors.put(doorId, newdoor);
}
public List<Integer> getPlayers()
{
return _players;
}
public List<L2Npc> getNpcs()
{
return _npcs;
}
public Collection<L2DoorInstance> getDoors()
{
return _doors.values();
}
public L2DoorInstance getDoor(int id)
{
return _doors.get(id);
}
public long getInstanceEndTime()
{
return _instanceEndTime;
}
public long getInstanceStartTime()
{
return _instanceStartTime;
}
public boolean isShowTimer()
{
return _showTimer;
}
public boolean isTimerIncrease()
{
return _isTimerIncrease;
}
public String getTimerText()
{
return _timerText;
}
/**
* @return the spawn location for this instance to be used when enter in instance
*/
public List<Location> getEnterLocs()
{
return _enterLocations;
}
/**
* Sets the spawn location for this instance to be used when enter in instance
* @param loc
*/
public void addEnterLoc(Location loc)
{
_enterLocations.add(loc);
}
/**
* @return the spawn location for this instance to be used when leaving the instance
*/
public Location getExitLoc()
{
return _exitLocation;
}
/**
* Sets the spawn location for this instance to be used when leaving the instance
* @param loc
*/
public void setExitLoc(Location loc)
{
_exitLocation = loc;
}
public void removePlayers()
{
for (Integer objectId : _players)
{
final L2PcInstance player = L2World.getInstance().getPlayer(objectId);
if ((player != null) && (player.getInstanceId() == getId()))
{
player.setInstanceId(0);
if (getExitLoc() != null)
{
player.teleToLocation(getExitLoc(), true);
}
else
{
player.teleToLocation(TeleportWhereType.TOWN);
}
}
}
_players.clear();
}
public void removeNpcs()
{
for (L2Npc mob : _npcs)
{
if (mob != null)
{
if (mob.getSpawn() != null)
{
mob.getSpawn().stopRespawn();
}
mob.deleteMe();
}
}
_npcs.clear();
_manualSpawn.clear();
}
public void removeSpawnedNpcs()
{
_npcs.stream().filter(Objects::nonNull).forEach(L2Npc::deleteMe);
_npcs.clear();
}
public void removeDoors()
{
for (L2DoorInstance door : _doors.values())
{
if (door != null)
{
final L2WorldRegion region = door.getWorldRegion();
door.decayMe();
if (region != null)
{
region.removeVisibleObject(door);
}
door.getKnownList().removeAllKnownObjects();
L2World.getInstance().removeObject(door);
}
}
_doors.clear();
}
/**
* Spawns group of instance NPC's
* @param groupName - name of group from XML definition to spawn
* @return list of spawned NPC's
*/
public List<L2Npc> spawnGroup(String groupName)
{
List<L2Npc> ret = null;
if (_manualSpawn.containsKey(groupName))
{
final List<L2Spawn> manualSpawn = _manualSpawn.get(groupName);
ret = new ArrayList<>(manualSpawn.size());
for (L2Spawn spawnDat : manualSpawn)
{
ret.add(spawnDat.doSpawn());
}
}
else
{
_log.warning(getName() + " instance: cannot spawn NPC's, wrong group name: " + groupName);
}
return ret;
}
public void loadInstanceTemplate(String filename)
{
Document doc = null;
final File xml = new File(Config.DATAPACK_ROOT, "instances/" + filename);
try
{
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setIgnoringComments(true);
doc = factory.newDocumentBuilder().parse(xml);
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("instance".equalsIgnoreCase(n.getNodeName()))
{
parseInstance(n);
}
}
}
catch (IOException e)
{
_log.log(Level.WARNING, "Instance: can not find " + xml.getAbsolutePath() + " ! " + e.getMessage(), e);
}
catch (Exception e)
{
_log.log(Level.WARNING, "Instance: error while loading " + xml.getAbsolutePath() + " ! " + e.getMessage(), e);
}
}
private void parseInstance(Node n) throws Exception
{
_name = n.getAttributes().getNamedItem("name").getNodeValue();
Node a = n.getAttributes().getNamedItem("ejectTime");
if (a != null)
{
_ejectTime = 1000 * Integer.parseInt(a.getNodeValue());
}
a = n.getAttributes().getNamedItem("allowRandomWalk");
if (a != null)
{
_allowRandomWalk = Boolean.parseBoolean(a.getNodeValue());
}
final Node first = n.getFirstChild();
for (n = first; n != null; n = n.getNextSibling())
{
switch (n.getNodeName().toLowerCase())
{
case "activitytime":
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
_checkTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(Integer.parseInt(a.getNodeValue()) * 60000), 15000);
_instanceEndTime = System.currentTimeMillis() + (Long.parseLong(a.getNodeValue()) * 60000) + 15000;
}
break;
}
case "allowsummon":
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
setAllowSummon(Boolean.parseBoolean(a.getNodeValue()));
}
break;
}
case "emptydestroytime":
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
_emptyDestroyTime = Long.parseLong(a.getNodeValue()) * 1000;
}
break;
}
case "showtimer":
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
_showTimer = Boolean.parseBoolean(a.getNodeValue());
}
a = n.getAttributes().getNamedItem("increase");
if (a != null)
{
_isTimerIncrease = Boolean.parseBoolean(a.getNodeValue());
}
a = n.getAttributes().getNamedItem("text");
if (a != null)
{
_timerText = a.getNodeValue();
}
break;
}
case "pvpinstance":
{
a = n.getAttributes().getNamedItem("val");
if (a != null)
{
setPvPInstance(Boolean.parseBoolean(a.getNodeValue()));
}
break;
}
case "doorlist":
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
int doorId = 0;
if ("door".equalsIgnoreCase(d.getNodeName()))
{
doorId = Integer.parseInt(d.getAttributes().getNamedItem("doorId").getNodeValue());
final StatsSet set = new StatsSet();
set.add(DoorData.getInstance().getDoorTemplate(doorId));
for (Node bean = d.getFirstChild(); bean != null; bean = bean.getNextSibling())
{
if ("set".equalsIgnoreCase(bean.getNodeName()))
{
final NamedNodeMap attrs = bean.getAttributes();
final String setname = attrs.getNamedItem("name").getNodeValue();
final String value = attrs.getNamedItem("val").getNodeValue();
set.set(setname, value);
}
}
addDoor(doorId, set);
}
}
break;
}
case "spawnlist":
{
for (Node group = n.getFirstChild(); group != null; group = group.getNextSibling())
{
if ("group".equalsIgnoreCase(group.getNodeName()))
{
final String spawnGroup = group.getAttributes().getNamedItem("name").getNodeValue();
final List<L2Spawn> manualSpawn = new ArrayList<>();
for (Node d = group.getFirstChild(); d != null; d = d.getNextSibling())
{
int npcId = 0, x = 0, y = 0, z = 0, heading = 0, respawn = 0, respawnRandom = 0, delay = -1;
Boolean allowRandomWalk = null;
String areaName = null;
int globalMapId = 0;
if ("spawn".equalsIgnoreCase(d.getNodeName()))
{
npcId = Integer.parseInt(d.getAttributes().getNamedItem("npcId").getNodeValue());
x = Integer.parseInt(d.getAttributes().getNamedItem("x").getNodeValue());
y = Integer.parseInt(d.getAttributes().getNamedItem("y").getNodeValue());
z = Integer.parseInt(d.getAttributes().getNamedItem("z").getNodeValue());
heading = Integer.parseInt(d.getAttributes().getNamedItem("heading").getNodeValue());
respawn = Integer.parseInt(d.getAttributes().getNamedItem("respawn").getNodeValue());
Node node = d.getAttributes().getNamedItem("onKillDelay");
if (node != null)
{
delay = Integer.parseInt(node.getNodeValue());
}
node = d.getAttributes().getNamedItem("respawnRandom");
if (node != null)
{
respawnRandom = Integer.parseInt(node.getNodeValue());
}
node = d.getAttributes().getNamedItem("allowRandomWalk");
if (d.getAttributes().getNamedItem("allowRandomWalk") != null)
{
allowRandomWalk = Boolean.valueOf(node.getNodeValue());
}
node = d.getAttributes().getNamedItem("areaName");
if (d.getAttributes().getNamedItem("areaName") != null)
{
areaName = node.getNodeValue();
}
node = d.getAttributes().getNamedItem("globalMapId");
if (node != null)
{
globalMapId = Integer.parseInt(node.getNodeValue());
}
final L2Spawn spawnDat = new L2Spawn(npcId);
spawnDat.setX(x);
spawnDat.setY(y);
spawnDat.setZ(z);
spawnDat.setAmount(1);
spawnDat.setHeading(heading);
spawnDat.setRespawnDelay(respawn, respawnRandom);
if (respawn == 0)
{
spawnDat.stopRespawn();
}
else
{
spawnDat.startRespawn();
}
spawnDat.setInstanceId(getId());
if (allowRandomWalk == null)
{
spawnDat.setIsNoRndWalk(!_allowRandomWalk);
}
else
{
spawnDat.setIsNoRndWalk(!allowRandomWalk);
}
spawnDat.setAreaName(areaName);
spawnDat.setGlobalMapId(globalMapId);
if (spawnGroup.equals("general"))
{
final L2Npc spawned = spawnDat.doSpawn();
if ((delay >= 0) && (spawned instanceof L2Attackable))
{
((L2Attackable) spawned).setOnKillDelay(delay);
}
}
else
{
manualSpawn.add(spawnDat);
}
}
}
if (!manualSpawn.isEmpty())
{
_manualSpawn.put(spawnGroup, manualSpawn);
}
}
}
break;
}
case "exitpoint":
{
final int x = Integer.parseInt(n.getAttributes().getNamedItem("x").getNodeValue());
final int y = Integer.parseInt(n.getAttributes().getNamedItem("y").getNodeValue());
final int z = Integer.parseInt(n.getAttributes().getNamedItem("z").getNodeValue());
_exitLocation = new Location(x, y, z);
break;
}
case "spawnpoints":
{
_enterLocations = new ArrayList<>();
for (Node loc = n.getFirstChild(); loc != null; loc = loc.getNextSibling())
{
if (loc.getNodeName().equals("Location"))
{
try
{
final int x = Integer.parseInt(loc.getAttributes().getNamedItem("x").getNodeValue());
final int y = Integer.parseInt(loc.getAttributes().getNamedItem("y").getNodeValue());
final int z = Integer.parseInt(loc.getAttributes().getNamedItem("z").getNodeValue());
_enterLocations.add(new Location(x, y, z));
}
catch (Exception e)
{
_log.log(Level.WARNING, "Error parsing instance xml: " + e.getMessage(), e);
}
}
}
break;
}
case "reenter":
{
a = n.getAttributes().getNamedItem("additionStyle");
if (a != null)
{
_type = InstanceReenterType.valueOf(a.getNodeValue());
}
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
long time = -1;
DayOfWeek day = null;
int hour = -1;
int minute = -1;
if ("reset".equalsIgnoreCase(d.getNodeName()))
{
a = d.getAttributes().getNamedItem("time");
if (a != null)
{
time = Long.parseLong(a.getNodeValue());
if (time > 0)
{
_resetData.add(new InstanceReenterTimeHolder(time));
break;
}
}
else if (time == -1)
{
a = d.getAttributes().getNamedItem("day");
if (a != null)
{
day = DayOfWeek.valueOf(a.getNodeValue().toUpperCase());
}
a = d.getAttributes().getNamedItem("hour");
if (a != null)
{
hour = Integer.parseInt(a.getNodeValue());
}
a = d.getAttributes().getNamedItem("minute");
if (a != null)
{
minute = Integer.parseInt(a.getNodeValue());
}
_resetData.add(new InstanceReenterTimeHolder(day, hour, minute));
}
}
}
break;
}
case "removebuffs":
{
a = n.getAttributes().getNamedItem("type");
if (a != null)
{
_removeBuffType = InstanceRemoveBuffType.valueOf(a.getNodeValue().toUpperCase());
}
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("skill".equalsIgnoreCase(d.getNodeName()))
{
a = d.getAttributes().getNamedItem("id");
if (a != null)
{
_exceptionList.add(Integer.parseInt(a.getNodeValue()));
}
}
}
break;
}
}
}
}
protected void doCheckTimeUp(int remaining)
{
CreatureSay cs = null;
int timeLeft;
int interval;
if (_players.isEmpty() && (_emptyDestroyTime == 0))
{
remaining = 0;
interval = 500;
}
else if (_players.isEmpty() && (_emptyDestroyTime > 0))
{
final Long emptyTimeLeft = (_lastLeft + _emptyDestroyTime) - System.currentTimeMillis();
if (emptyTimeLeft <= 0)
{
interval = 0;
remaining = 0;
}
else if ((remaining > 300000) && (emptyTimeLeft > 300000))
{
interval = 300000;
remaining = remaining - 300000;
}
else if ((remaining > 60000) && (emptyTimeLeft > 60000))
{
interval = 60000;
remaining = remaining - 60000;
}
else if ((remaining > 30000) && (emptyTimeLeft > 30000))
{
interval = 30000;
remaining = remaining - 30000;
}
else
{
interval = 10000;
remaining = remaining - 10000;
}
}
else if (remaining > 300000)
{
timeLeft = remaining / 60000;
interval = 300000;
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.THIS_DUNGEON_WILL_EXPIRE_IN_S1_MINUTE_S_YOU_WILL_BE_FORCED_OUT_OF_THE_DUNGEON_WHEN_THE_TIME_EXPIRES);
sm.addString(Integer.toString(timeLeft));
Broadcast.toPlayersInInstance(sm, getId());
remaining = remaining - 300000;
}
else if (remaining > 60000)
{
timeLeft = remaining / 60000;
interval = 60000;
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.THIS_DUNGEON_WILL_EXPIRE_IN_S1_MINUTE_S_YOU_WILL_BE_FORCED_OUT_OF_THE_DUNGEON_WHEN_THE_TIME_EXPIRES);
sm.addString(Integer.toString(timeLeft));
Broadcast.toPlayersInInstance(sm, getId());
remaining = remaining - 60000;
}
else if (remaining > 30000)
{
timeLeft = remaining / 1000;
interval = 30000;
cs = new CreatureSay(0, ChatType.ALLIANCE, "Notice", timeLeft + " seconds left.");
remaining = remaining - 30000;
}
else
{
timeLeft = remaining / 1000;
interval = 10000;
cs = new CreatureSay(0, ChatType.ALLIANCE, "Notice", timeLeft + " seconds left.");
remaining = remaining - 10000;
}
if (cs != null)
{
for (Integer objectId : _players)
{
final L2PcInstance player = L2World.getInstance().getPlayer(objectId);
if ((player != null) && (player.getInstanceId() == getId()))
{
player.sendPacket(cs);
}
}
}
cancelTimer();
if (remaining >= 10000)
{
_checkTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(remaining), interval);
}
else
{
_checkTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new TimeUp(), interval);
}
}
public void cancelTimer()
{
if (_checkTimeUpTask != null)
{
_checkTimeUpTask.cancel(true);
}
}
public void cancelEjectDeadPlayer(L2PcInstance player)
{
final ScheduledFuture<?> task = _ejectDeadTasks.remove(player.getObjectId());
if (task != null)
{
task.cancel(true);
}
}
public void addEjectDeadTask(L2PcInstance player)
{
if ((player != null))
{
_ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.getInstance().scheduleGeneral(() ->
{
if (player.isDead() && (player.getInstanceId() == getId()))
{
player.setInstanceId(0);
if (getExitLoc() != null)
{
player.teleToLocation(getExitLoc(), true);
}
else
{
player.teleToLocation(TeleportWhereType.TOWN);
}
}
}, _ejectTime));
}
}
/**
* @param killer the character that killed the {@code victim}
* @param victim the character that was killed by the {@code killer}
*/
public final void notifyDeath(L2Character killer, L2Character victim)
{
final InstanceWorld instance = InstanceManager.getInstance().getPlayerWorld(victim.getActingPlayer());
if (instance != null)
{
instance.onDeath(killer, victim);
}
}
public class CheckTimeUp implements Runnable
{
private final int _remaining;
public CheckTimeUp(int remaining)
{
_remaining = remaining;
}
@Override
public void run()
{
doCheckTimeUp(_remaining);
}
}
public class TimeUp implements Runnable
{
@Override
public void run()
{
InstanceManager.getInstance().destroyInstance(getId());
}
}
public InstanceReenterType getReenterType()
{
return _type;
}
public void setReenterType(InstanceReenterType type)
{
_type = type;
}
public List<InstanceReenterTimeHolder> getReenterData()
{
return _resetData;
}
public boolean isRemoveBuffEnabled()
{
return getRemoveBuffType() != InstanceRemoveBuffType.NONE;
}
public InstanceRemoveBuffType getRemoveBuffType()
{
return _removeBuffType;
}
public List<Integer> getBuffExceptionList()
{
return _exceptionList;
}
}

View File

@ -0,0 +1,565 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.cache.HtmCache;
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
import com.l2jmobius.gameserver.datatables.SpawnTable;
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
import com.l2jmobius.gameserver.model.L2Spawn;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.PlayerEventHolder;
import com.l2jmobius.gameserver.network.serverpackets.CharInfo;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
/**
* @author Nik
* @Since 2011/05/17 21:51:39
*/
public class L2Event
{
protected static final Logger _log = Logger.getLogger(L2Event.class.getName());
public static EventState eventState = EventState.OFF;
public static String _eventName = "";
public static String _eventCreator = "";
public static String _eventInfo = "";
public static int _teamsNumber = 0;
public static final Map<Integer, String> _teamNames = new ConcurrentHashMap<>();
public static final List<L2PcInstance> _registeredPlayers = new CopyOnWriteArrayList<>();
public static final Map<Integer, List<L2PcInstance>> _teams = new ConcurrentHashMap<>();
public static int _npcId = 0;
private static final Map<L2PcInstance, PlayerEventHolder> _connectionLossData = new ConcurrentHashMap<>();
public enum EventState
{
OFF, // Not running
STANDBY, // Waiting for participants to register
ON // Registration is over and the event has started.
}
/**
* @param player
* @return The team ID where the player is in, or -1 if player is null or team not found.
*/
public static int getPlayerTeamId(L2PcInstance player)
{
if (player == null)
{
return -1;
}
for (Entry<Integer, List<L2PcInstance>> team : _teams.entrySet())
{
if (team.getValue().contains(player))
{
return team.getKey();
}
}
return -1;
}
public static List<L2PcInstance> getTopNKillers(int n)
{
final Map<L2PcInstance, Integer> tmp = new HashMap<>();
for (List<L2PcInstance> teamList : _teams.values())
{
for (L2PcInstance player : teamList)
{
if (player.getEventStatus() == null)
{
continue;
}
tmp.put(player, player.getEventStatus().getKills().size());
}
}
sortByValue(tmp);
// If the map size is less than "n", n will be as much as the map size
if (tmp.size() <= n)
{
return new ArrayList<>(tmp.keySet());
}
final List<L2PcInstance> toReturn = new ArrayList<>(tmp.keySet());
return toReturn.subList(1, n);
}
public static void showEventHtml(L2PcInstance player, String objectid)
{
// TODO: work on this
if (eventState == EventState.STANDBY)
{
try
{
final String htmContent;
final NpcHtmlMessage html = new NpcHtmlMessage(Integer.parseInt(objectid));
if (_registeredPlayers.contains(player))
{
htmContent = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), "html/mods/EventEngine/Participating.htm");
}
else
{
htmContent = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), "html/mods/EventEngine/Participation.htm");
}
if (htmContent != null)
{
html.setHtml(htmContent);
}
html.replace("%objectId%", objectid); // Yeah, we need this.
html.replace("%eventName%", _eventName);
html.replace("%eventCreator%", _eventCreator);
html.replace("%eventInfo%", _eventInfo);
player.sendPacket(html);
}
catch (Exception e)
{
_log.log(Level.WARNING, "Exception on showEventHtml(): " + e.getMessage(), e);
}
}
}
/**
* Spawns an event participation NPC near the player. The npc id used to spawning is L2Event._npcId
* @param target
*/
public static void spawnEventNpc(L2PcInstance target)
{
try
{
final L2Spawn spawn = new L2Spawn(_npcId);
spawn.setX(target.getX() + 50);
spawn.setY(target.getY() + 50);
spawn.setZ(target.getZ());
spawn.setAmount(1);
spawn.setHeading(target.getHeading());
spawn.stopRespawn();
SpawnTable.getInstance().addNewSpawn(spawn, false);
spawn.init();
spawn.getLastSpawn().setCurrentHp(999999999);
spawn.getLastSpawn().setTitle(_eventName);
spawn.getLastSpawn().setEventMob(true);
// spawn.getLastSpawn().decayMe();
// spawn.getLastSpawn().spawnMe(spawn.getLastSpawn().getX(), spawn.getLastSpawn().getY(), spawn.getLastSpawn().getZ());
spawn.getLastSpawn().broadcastPacket(new MagicSkillUse(spawn.getLastSpawn(), spawn.getLastSpawn(), 1034, 1, 1, 1));
// _npcs.add(spawn.getLastSpawn());
}
catch (Exception e)
{
_log.log(Level.WARNING, "Exception on spawn(): " + e.getMessage(), e);
}
}
/**
* Zoey76: TODO: Rewrite this in a way that doesn't iterate over all spawns.
*/
public static void unspawnEventNpcs()
{
SpawnTable.getInstance().forEachSpawn(spawn ->
{
final L2Npc npc = spawn.getLastSpawn();
if ((npc != null) && npc.isEventMob())
{
npc.deleteMe();
spawn.stopRespawn();
SpawnTable.getInstance().deleteSpawn(spawn, false);
}
return true;
});
}
/**
* @param player
* @return False: If player is null, his event status is null or the event state is off. True: if the player is inside the _registeredPlayers list while the event state is STANDBY. If the event state is ON, it will check if the player is inside in one of the teams.
*/
public static boolean isParticipant(L2PcInstance player)
{
if ((player == null) || (player.getEventStatus() == null))
{
return false;
}
switch (eventState)
{
case OFF:
{
return false;
}
case STANDBY:
{
return _registeredPlayers.contains(player);
}
case ON:
{
for (List<L2PcInstance> teamList : _teams.values())
{
if (teamList.contains(player))
{
return true;
}
}
}
}
return false;
}
/**
* Adds the player to the list of participants. If the event state is NOT STANDBY, the player wont be registered.
* @param player
*/
public static void registerPlayer(L2PcInstance player)
{
if (eventState != EventState.STANDBY)
{
player.sendMessage("The registration period for this event is over.");
return;
}
if ((Config.L2JMOD_DUALBOX_CHECK_MAX_L2EVENT_PARTICIPANTS_PER_IP == 0) || AntiFeedManager.getInstance().tryAddPlayer(AntiFeedManager.L2EVENT_ID, player, Config.L2JMOD_DUALBOX_CHECK_MAX_L2EVENT_PARTICIPANTS_PER_IP))
{
_registeredPlayers.add(player);
}
else
{
player.sendMessage("You have reached the maximum allowed participants per IP.");
return;
}
}
/**
* Removes the player from the participating players and the teams and restores his init stats before he registered at the event (loc, pvp, pk, title etc)
* @param player
*/
public static void removeAndResetPlayer(L2PcInstance player)
{
try
{
if (isParticipant(player))
{
if (player.isDead())
{
player.restoreExp(100.0);
player.doRevive();
player.setCurrentHpMp(player.getMaxHp(), player.getMaxMp());
player.setCurrentCp(player.getMaxCp());
}
player.getPoly().setPolyInfo(null, "1");
player.decayMe();
player.spawnMe(player.getX(), player.getY(), player.getZ());
final CharInfo info1 = new CharInfo(player);
player.broadcastPacket(info1);
final UserInfo info2 = new UserInfo(player);
player.sendPacket(info2);
player.stopTransformation(true);
}
if (player.getEventStatus() != null)
{
player.getEventStatus().restorePlayerStats();
}
player.setEventStatus(null);
_registeredPlayers.remove(player);
final int teamId = getPlayerTeamId(player);
if (_teams.containsKey(teamId))
{
_teams.get(teamId).remove(player);
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "Error at unregisterAndResetPlayer in the event:" + e.getMessage(), e);
}
}
/**
* The player's event status will be saved at _connectionLossData
* @param player
*/
public static void savePlayerEventStatus(L2PcInstance player)
{
_connectionLossData.put(player, player.getEventStatus());
}
/**
* If _connectionLossData contains the player, it will restore the player's event status. Also it will remove the player from the _connectionLossData.
* @param player
*/
public static void restorePlayerEventStatus(L2PcInstance player)
{
if (_connectionLossData.containsKey(player))
{
player.setEventStatus(_connectionLossData.get(player));
_connectionLossData.remove(player);
}
}
/**
* If the event is ON or STANDBY, it will not start. Sets the event state to STANDBY and spawns registration NPCs
* @return a string with information if the event participation has been successfully started or not.
*/
public static String startEventParticipation()
{
try
{
switch (eventState)
{
case ON:
{
return "Cannot start event, it is already on.";
}
case STANDBY:
{
return "Cannot start event, it is on standby mode.";
}
case OFF: // Event is off, so no problem turning it on.
{
eventState = EventState.STANDBY;
break;
}
}
// Register the event at AntiFeedManager and clean it for just in case if the event is already registered.
AntiFeedManager.getInstance().registerEvent(AntiFeedManager.L2EVENT_ID);
AntiFeedManager.getInstance().clear(AntiFeedManager.L2EVENT_ID);
// Just in case
unspawnEventNpcs();
_registeredPlayers.clear();
// _npcs.clear();
if (NpcData.getInstance().getTemplate(_npcId) == null)
{
return "Cannot start event, invalid npc id.";
}
try (FileReader fr = new FileReader(Config.DATAPACK_ROOT + "/events/" + _eventName);
BufferedReader br = new BufferedReader(fr))
{
_eventCreator = br.readLine();
_eventInfo = br.readLine();
}
final List<L2PcInstance> temp = new LinkedList<>();
for (L2PcInstance player : L2World.getInstance().getPlayers())
{
if (!player.isOnline())
{
continue;
}
if (!temp.contains(player))
{
spawnEventNpc(player);
temp.add(player);
}
for (L2PcInstance playertemp : player.getKnownList().getKnownPlayers().values())
{
if ((Math.abs(playertemp.getX() - player.getX()) < 1000) && (Math.abs(playertemp.getY() - player.getY()) < 1000) && (Math.abs(playertemp.getZ() - player.getZ()) < 1000))
{
temp.add(playertemp);
}
}
}
}
catch (Exception e)
{
_log.warning("L2Event: " + e.getMessage());
return "Cannot start event participation, an error has occured.";
}
return "The event participation has been successfully started.";
}
/**
* If the event is ON or OFF, it will not start. Sets the event state to ON, creates the teams, adds the registered players ordered by level at the teams and adds a new event status to the players.
* @return a string with information if the event has been successfully started or not.
*/
public static String startEvent()
{
try
{
switch (eventState)
{
case ON:
{
return "Cannot start event, it is already on.";
}
case STANDBY:
{
eventState = EventState.ON;
break;
}
case OFF: // Event is off, so no problem turning it on.
{
return "Cannot start event, it is off. Participation start is required.";
}
}
// Clean the things we will use, just in case.
unspawnEventNpcs();
_teams.clear();
_connectionLossData.clear();
// Insert empty lists at _teams.
for (int i = 0; i < _teamsNumber; i++)
{
_teams.put(i + 1, new CopyOnWriteArrayList<L2PcInstance>());
}
int i = 0;
while (!_registeredPlayers.isEmpty())
{
// Get the player with the biggest level
int max = 0;
L2PcInstance biggestLvlPlayer = null;
for (L2PcInstance player : _registeredPlayers)
{
if (player == null)
{
continue;
}
if (max < player.getLevel())
{
max = player.getLevel();
biggestLvlPlayer = player;
}
}
if (biggestLvlPlayer == null)
{
continue;
}
_registeredPlayers.remove(biggestLvlPlayer);
_teams.get(i + 1).add(biggestLvlPlayer);
biggestLvlPlayer.setEventStatus();
i = (i + 1) % _teamsNumber;
}
}
catch (Exception e)
{
_log.warning("L2Event: " + e.getMessage());
return "Cannot start event, an error has occured.";
}
return "The event has been successfully started.";
}
/**
* If the event state is OFF, it will not finish. Sets the event state to OFF, unregisters and resets the players, unspawns and clers the event NPCs, clears the teams, registered players, connection loss data, sets the teams number to 0, sets the event name to empty.
* @return a string with information if the event has been successfully stopped or not.
*/
public static String finishEvent()
{
switch (eventState)
{
case OFF:
{
return "Cannot finish event, it is already off.";
}
case STANDBY:
{
for (L2PcInstance player : _registeredPlayers)
{
removeAndResetPlayer(player);
}
unspawnEventNpcs();
// _npcs.clear();
_registeredPlayers.clear();
_teams.clear();
_connectionLossData.clear();
_teamsNumber = 0;
_eventName = "";
eventState = EventState.OFF;
return "The event has been stopped at STANDBY mode, all players unregistered and all event npcs unspawned.";
}
case ON:
{
for (List<L2PcInstance> teamList : _teams.values())
{
for (L2PcInstance player : teamList)
{
removeAndResetPlayer(player);
}
}
eventState = EventState.OFF;
AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
unspawnEventNpcs(); // Just in case
// _npcs.clear();
_registeredPlayers.clear();
_teams.clear();
_connectionLossData.clear();
_teamsNumber = 0;
_eventName = "";
_npcId = 0;
_eventCreator = "";
_eventInfo = "";
return "The event has been stopped, all players unregistered and all event npcs unspawned.";
}
}
return "The event has been successfully finished.";
}
private static final Map<L2PcInstance, Integer> sortByValue(Map<L2PcInstance, Integer> unsortMap)
{
final List<Entry<L2PcInstance, Integer>> list = new LinkedList<>(unsortMap.entrySet());
list.sort(Comparator.comparing(Entry::getValue));
final Map<L2PcInstance, Integer> sortedMap = new LinkedHashMap<>();
for (Entry<L2PcInstance, Integer> entry : list)
{
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
}

View File

@ -0,0 +1,488 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.ScheduledFuture;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
import com.l2jmobius.gameserver.enums.MailType;
import com.l2jmobius.gameserver.idfactory.IdFactory;
import com.l2jmobius.gameserver.instancemanager.MailManager;
import com.l2jmobius.gameserver.model.itemcontainer.Mail;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.util.Rnd;
/**
* @author Migi, DS
*/
public class Message
{
private static final int EXPIRATION = 360; // 15 days
private static final int COD_EXPIRATION = 12; // 12 hours
private static final int UNLOAD_ATTACHMENTS_INTERVAL = 900000; // 15-30 mins
// post state
public static final int DELETED = 0;
public static final int READED = 1;
public static final int REJECTED = 2;
private final int _messageId, _senderId, _receiverId;
private final long _expiration;
private String _senderName = null;
private String _receiverName = null;
private final String _subject, _content;
private boolean _unread, _returned;
private MailType _messageType = MailType.REGULAR;
private boolean _deletedBySender;
private boolean _deletedByReceiver;
private final long _reqAdena;
private boolean _hasAttachments;
private Mail _attachments = null;
private ScheduledFuture<?> _unloadTask = null;
private int _itemId;
private int _enchantLvl;
private final int[] _elementals = new int[6];
/*
* Constructor for restoring from DB.
*/
public Message(ResultSet rset) throws SQLException
{
_messageId = rset.getInt("messageId");
_senderId = rset.getInt("senderId");
_receiverId = rset.getInt("receiverId");
_subject = rset.getString("subject");
_content = rset.getString("content");
_expiration = rset.getLong("expiration");
_reqAdena = rset.getLong("reqAdena");
_hasAttachments = rset.getBoolean("hasAttachments");
_unread = rset.getBoolean("isUnread");
_deletedBySender = rset.getBoolean("isDeletedBySender");
_deletedByReceiver = rset.getBoolean("isDeletedByReceiver");
_messageType = MailType.values()[rset.getInt("sendBySystem")];
_returned = rset.getBoolean("isReturned");
_itemId = rset.getInt("itemId");
_enchantLvl = rset.getInt("enchantLvl");
final String elemental = rset.getString("elementals");
if (elemental != null)
{
final String[] elemDef = elemental.split(";");
for (int i = 0; i < 6; i++)
{
_elementals[i] = Integer.parseInt(elemDef[i]);
}
}
}
/*
* This constructor used for creating new message.
*/
public Message(int senderId, int receiverId, boolean isCod, String subject, String text, long reqAdena)
{
_messageId = IdFactory.getInstance().getNextId();
_senderId = senderId;
_receiverId = receiverId;
_subject = subject;
_content = text;
_expiration = (isCod ? System.currentTimeMillis() + (COD_EXPIRATION * 3600000) : System.currentTimeMillis() + (EXPIRATION * 3600000));
_hasAttachments = false;
_unread = true;
_deletedBySender = false;
_deletedByReceiver = false;
_reqAdena = reqAdena;
}
/*
* This constructor used for System Mails
*/
public Message(int receiverId, String subject, String content, MailType sendBySystem)
{
_messageId = IdFactory.getInstance().getNextId();
_senderId = -1;
_receiverId = receiverId;
_subject = subject;
_content = content;
_expiration = System.currentTimeMillis() + (EXPIRATION * 3600000);
_reqAdena = 0;
_hasAttachments = false;
_unread = true;
_deletedBySender = true;
_deletedByReceiver = false;
_messageType = sendBySystem;
_returned = false;
}
/*
* This constructor is used for creating new System message
*/
public Message(int senderId, int receiverId, String subject, String content, MailType sendBySystem)
{
_messageId = IdFactory.getInstance().getNextId();
_senderId = senderId;
_receiverId = receiverId;
_subject = subject;
_content = content;
_expiration = System.currentTimeMillis() + (EXPIRATION * 3600000);
_hasAttachments = false;
_unread = true;
_deletedBySender = true;
_deletedByReceiver = false;
_reqAdena = 0;
_messageType = sendBySystem;
}
/*
* This constructor used for auto-generation of the "return attachments" message
*/
public Message(Message msg)
{
_messageId = IdFactory.getInstance().getNextId();
_senderId = msg.getSenderId();
_receiverId = msg.getSenderId();
_subject = "";
_content = "";
_expiration = System.currentTimeMillis() + (EXPIRATION * 3600000);
_unread = true;
_deletedBySender = true;
_deletedByReceiver = false;
_messageType = MailType.REGULAR;
_returned = true;
_reqAdena = 0;
_hasAttachments = true;
_attachments = msg.getAttachments();
msg.removeAttachments();
_attachments.setNewMessageId(_messageId);
_unloadTask = ThreadPoolManager.getInstance().scheduleGeneral(new AttachmentsUnloadTask(this), UNLOAD_ATTACHMENTS_INTERVAL + Rnd.get(UNLOAD_ATTACHMENTS_INTERVAL));
}
public Message(int receiverId, L2ItemInstance item, MailType mailType)
{
_messageId = IdFactory.getInstance().getNextId();
_senderId = -1;
_receiverId = receiverId;
_subject = "";
_content = item.getName();
_expiration = System.currentTimeMillis() + (EXPIRATION * 3600000);
_unread = true;
_deletedBySender = true;
_messageType = mailType;
_returned = false;
_reqAdena = 0;
if (mailType == MailType.COMMISSION_ITEM_SOLD)
{
_hasAttachments = false;
_itemId = item.getId();
_enchantLvl = item.getEnchantLevel();
if (item.isArmor())
{
for (int i = 0; i < 6; i++)
{
_elementals[i] = item.getElementDefAttr((byte) i);
}
}
else if (item.isWeapon() && (item.getAttackElementType() >= 0))
{
_elementals[item.getAttackElementType()] = item.getAttackElementPower();
}
}
else if (mailType == MailType.COMMISSION_ITEM_RETURNED)
{
final Mail attachement = createAttachments();
attachement.addItem("CommissionReturnItem", item, null, null);
}
}
public static final PreparedStatement getStatement(Message msg, Connection con) throws SQLException
{
final PreparedStatement stmt = con.prepareStatement("INSERT INTO messages (messageId, senderId, receiverId, subject, content, expiration, reqAdena, hasAttachments, isUnread, isDeletedBySender, isDeletedByReceiver, sendBySystem, isReturned, itemId, enchantLvl, elementals) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
stmt.setInt(1, msg._messageId);
stmt.setInt(2, msg._senderId);
stmt.setInt(3, msg._receiverId);
stmt.setString(4, msg._subject);
stmt.setString(5, msg._content);
stmt.setLong(6, msg._expiration);
stmt.setLong(7, msg._reqAdena);
stmt.setString(8, String.valueOf(msg._hasAttachments));
stmt.setString(9, String.valueOf(msg._unread));
stmt.setString(10, String.valueOf(msg._deletedBySender));
stmt.setString(11, String.valueOf(msg._deletedByReceiver));
stmt.setInt(12, msg._messageType.ordinal());
stmt.setString(13, String.valueOf(msg._returned));
stmt.setInt(14, msg._itemId);
stmt.setInt(15, msg._enchantLvl);
stmt.setString(16, msg._elementals[0] + ";" + msg._elementals[1] + ";" + msg._elementals[2] + ";" + msg._elementals[3] + ";" + msg._elementals[4] + ";" + msg._elementals[5]);
return stmt;
}
public final int getId()
{
return _messageId;
}
public final int getSenderId()
{
return _senderId;
}
public final int getReceiverId()
{
return _receiverId;
}
public final String getSenderName()
{
switch (_messageType)
{
case REGULAR:
{
_senderName = CharNameTable.getInstance().getNameById(_senderId);
break;
}
case PRIME_SHOP_GIFT: // Not in client, tbd
{
break;
}
case NEWS_INFORMER: // Handled by Sysstring in client
case NPC: // Handled by NpcName in client
case BIRTHDAY: // Handled by Sysstring in client
case COMMISSION_ITEM_SOLD: // Handled by Sysstring in client
case COMMISSION_ITEM_RETURNED: // Handled by Sysstring in client
case MENTOR_NPC: // Handled in client
default:
{
break;
}
}
return _senderName;
}
public final String getReceiverName()
{
if (_receiverName == null)
{
_receiverName = CharNameTable.getInstance().getNameById(_receiverId);
if (_receiverName == null)
{
_receiverName = "";
}
}
return _receiverName;
}
public final String getSubject()
{
return _subject;
}
public final String getContent()
{
return _content;
}
public final boolean isLocked()
{
return _reqAdena > 0;
}
public final long getExpiration()
{
return _expiration;
}
public final int getExpirationSeconds()
{
return (int) (_expiration / 1000);
}
public final boolean isUnread()
{
return _unread;
}
public final void markAsRead()
{
if (_unread)
{
_unread = false;
MailManager.getInstance().markAsReadInDb(_messageId);
}
}
public final boolean isDeletedBySender()
{
return _deletedBySender;
}
public final void setDeletedBySender()
{
if (!_deletedBySender)
{
_deletedBySender = true;
if (_deletedByReceiver)
{
MailManager.getInstance().deleteMessageInDb(_messageId);
}
else
{
MailManager.getInstance().markAsDeletedBySenderInDb(_messageId);
}
}
}
public final boolean isDeletedByReceiver()
{
return _deletedByReceiver;
}
public final void setDeletedByReceiver()
{
if (!_deletedByReceiver)
{
_deletedByReceiver = true;
if (_deletedBySender)
{
MailManager.getInstance().deleteMessageInDb(_messageId);
}
else
{
MailManager.getInstance().markAsDeletedByReceiverInDb(_messageId);
}
}
}
public final MailType getMailType()
{
return _messageType;
}
public final boolean isReturned()
{
return _returned;
}
public final void setIsReturned(boolean val)
{
_returned = val;
}
public final long getReqAdena()
{
return _reqAdena;
}
public final synchronized Mail getAttachments()
{
if (!_hasAttachments)
{
return null;
}
if (_attachments == null)
{
_attachments = new Mail(_senderId, _messageId);
_attachments.restore();
_unloadTask = ThreadPoolManager.getInstance().scheduleGeneral(new AttachmentsUnloadTask(this), UNLOAD_ATTACHMENTS_INTERVAL + Rnd.get(UNLOAD_ATTACHMENTS_INTERVAL));
}
return _attachments;
}
public final boolean hasAttachments()
{
return _hasAttachments;
}
public int getItemId()
{
return _itemId;
}
public int getEnchantLvl()
{
return _enchantLvl;
}
public int[] getElementals()
{
return _elementals;
}
public final synchronized void removeAttachments()
{
if (_attachments != null)
{
_attachments = null;
_hasAttachments = false;
MailManager.getInstance().removeAttachmentsInDb(_messageId);
if (_unloadTask != null)
{
_unloadTask.cancel(false);
}
}
}
public final synchronized Mail createAttachments()
{
if (_hasAttachments || (_attachments != null))
{
return null;
}
_attachments = new Mail(_senderId, _messageId);
_hasAttachments = true;
_unloadTask = ThreadPoolManager.getInstance().scheduleGeneral(new AttachmentsUnloadTask(this), UNLOAD_ATTACHMENTS_INTERVAL + Rnd.get(UNLOAD_ATTACHMENTS_INTERVAL));
return _attachments;
}
protected final synchronized void unloadAttachments()
{
if (_attachments != null)
{
_attachments.deleteMe();
_attachments = null;
}
}
static class AttachmentsUnloadTask implements Runnable
{
private Message _msg;
AttachmentsUnloadTask(Message msg)
{
_msg = msg;
}
@Override
public void run()
{
if (_msg != null)
{
_msg.unloadAttachments();
_msg = null;
}
}
}
}

View File

@ -0,0 +1,65 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.util.Calendar;
import java.util.List;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2SiegeClan;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
/**
* @author JIV
*/
public interface Siegable
{
public void startSiege();
public void endSiege();
public L2SiegeClan getAttackerClan(int clanId);
public L2SiegeClan getAttackerClan(L2Clan clan);
public List<L2SiegeClan> getAttackerClans();
public List<L2PcInstance> getAttackersInZone();
public boolean checkIsAttacker(L2Clan clan);
public L2SiegeClan getDefenderClan(int clanId);
public L2SiegeClan getDefenderClan(L2Clan clan);
public List<L2SiegeClan> getDefenderClans();
public boolean checkIsDefender(L2Clan clan);
public List<L2Npc> getFlag(L2Clan clan);
public Calendar getSiegeDate();
public boolean giveFame();
public int getFameFrequency();
public int getFameAmount();
public void updateSiege();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.interfaces.IEventListener;
/**
* @author UnAfraid
*/
public final class TvTEventListener implements IEventListener
{
private final L2PcInstance _player;
protected TvTEventListener(L2PcInstance player)
{
_player = player;
}
@Override
public boolean isOnEvent()
{
return TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getPlayer().getObjectId());
}
@Override
public boolean isBlockingExit()
{
return true;
}
@Override
public boolean isBlockingDeathPenalty()
{
return true;
}
@Override
public boolean canRevive()
{
return false;
}
@Override
public L2PcInstance getPlayer()
{
return _player;
}
}

View File

@ -0,0 +1,57 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
/**
* @author UnAfraid
*/
public class TvTEventPlayer
{
private final L2PcInstance _player;
protected TvTEventPlayer(L2PcInstance player)
{
_player = player;
}
public boolean isOnEvent()
{
return TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getPlayer().getObjectId());
}
public boolean isBlockingExit()
{
return true;
}
public boolean isBlockingDeathPenalty()
{
return true;
}
public boolean canRevive()
{
return false;
}
public L2PcInstance getPlayer()
{
return _player;
}
}

View File

@ -0,0 +1,160 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
/**
* @author HorridoJoho
*/
public class TvTEventTeam
{
/**
* The name of the team<br>
*/
private final String _name;
/**
* The team spot coordinated<br>
*/
private int[] _coordinates = new int[3];
/**
* The points of the team<br>
*/
private short _points;
/** Name and instance of all participated players in map. */
private final Map<Integer, L2PcInstance> _participatedPlayers = new ConcurrentHashMap<>();
/**
* C'tor initialize the team<br>
* <br>
* @param name as String<br>
* @param coordinates as int[]<br>
*/
public TvTEventTeam(String name, int[] coordinates)
{
_name = name;
_coordinates = coordinates;
_points = 0;
}
/**
* Adds a player to the team<br>
* <br>
* @param playerInstance as L2PcInstance<br>
* @return boolean: true if success, otherwise false<br>
*/
public boolean addPlayer(L2PcInstance playerInstance)
{
if (playerInstance == null)
{
return false;
}
_participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
return true;
}
/**
* Removes a player from the team
* @param playerObjectId
*/
public void removePlayer(int playerObjectId)
{
_participatedPlayers.remove(playerObjectId);
}
/**
* Increases the points of the team<br>
*/
public void increasePoints()
{
++_points;
}
/**
* Cleanup the team and make it ready for adding players again<br>
*/
public void cleanMe()
{
_participatedPlayers.clear();
_points = 0;
}
/**
* Is given player in this team?
* @param playerObjectId
* @return boolean: true if player is in this team, otherwise false
*/
public boolean containsPlayer(int playerObjectId)
{
return _participatedPlayers.containsKey(playerObjectId);
}
/**
* Returns the name of the team<br>
* <br>
* @return String: name of the team<br>
*/
public String getName()
{
return _name;
}
/**
* Returns the coordinates of the team spot<br>
* <br>
* @return int[]: team coordinates<br>
*/
public int[] getCoordinates()
{
return _coordinates;
}
/**
* Returns the points of the team<br>
* <br>
* @return short: team points<br>
*/
public short getPoints()
{
return _points;
}
/**
* Returns name and instance of all participated players in Map<br>
* <br>
* @return Map<String, L2PcInstance>: map of players in this team<br>
*/
public Map<Integer, L2PcInstance> getParticipatedPlayers()
{
return _participatedPlayers;
}
/**
* Returns player count of this team<br>
* <br>
* @return int: number of players in team<br>
*/
public int getParticipatedPlayerCount()
{
return _participatedPlayers.size();
}
}

View File

@ -0,0 +1,144 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.enums.DuelState;
import com.l2jmobius.gameserver.enums.Team;
import com.l2jmobius.gameserver.model.actor.L2Summon;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.util.Rnd;
public class TvTEventTeleporter implements Runnable
{
/** The instance of the player to teleport */
private L2PcInstance _playerInstance = null;
/** Coordinates of the spot to teleport to */
private int[] _coordinates = new int[3];
/** Admin removed this player from event */
private boolean _adminRemove = false;
/**
* Initialize the teleporter and start the delayed task.
* @param playerInstance
* @param coordinates
* @param fastSchedule
* @param adminRemove
*/
public TvTEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
{
_playerInstance = playerInstance;
_coordinates = coordinates;
_adminRemove = adminRemove;
final long delay = (TvTEvent.isStarted() ? Config.TVT_EVENT_RESPAWN_TELEPORT_DELAY : Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
}
/**
* The task method to teleport the player<br>
* 1. Unsummon pet if there is one<br>
* 2. Remove all effects<br>
* 3. Revive and full heal the player<br>
* 4. Teleport the player<br>
* 5. Broadcast status and user info
*/
@Override
public void run()
{
if (_playerInstance == null)
{
return;
}
final L2Summon summon = _playerInstance.getPet();
if (summon != null)
{
summon.unSummon(_playerInstance);
}
_playerInstance.getServitors().values().forEach(s -> s.unSummon(_playerInstance));
if ((Config.TVT_EVENT_EFFECTS_REMOVAL == 0) || ((Config.TVT_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != DuelState.INTERRUPTED)))))
{
_playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
}
if (_playerInstance.isInDuel())
{
_playerInstance.setDuelState(DuelState.INTERRUPTED);
}
final int TvTInstance = TvTEvent.getTvTEventInstance();
if (TvTInstance != 0)
{
if (TvTEvent.isStarted() && !_adminRemove)
{
_playerInstance.setInstanceId(TvTInstance);
}
else
{
_playerInstance.setInstanceId(0);
}
}
else
{
_playerInstance.setInstanceId(0);
}
_playerInstance.doRevive();
_playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
if (TvTEvent.isStarted() && !_adminRemove)
{
final int teamId = TvTEvent.getParticipantTeamId(_playerInstance.getObjectId()) + 1;
switch (teamId)
{
case 0:
{
_playerInstance.setTeam(Team.NONE);
break;
}
case 1:
{
_playerInstance.setTeam(Team.BLUE);
break;
}
case 2:
{
_playerInstance.setTeam(Team.RED);
break;
}
}
}
else
{
_playerInstance.setTeam(Team.NONE);
}
_playerInstance.setCurrentCp(_playerInstance.getMaxCp());
_playerInstance.setCurrentHp(_playerInstance.getMaxHp());
_playerInstance.setCurrentMp(_playerInstance.getMaxMp());
_playerInstance.broadcastStatusUpdate();
_playerInstance.broadcastUserInfo();
}
}

View File

@ -0,0 +1,297 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity;
import java.util.Calendar;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.util.Broadcast;
/**
* @author HorridoJoho
*/
public class TvTManager
{
protected static final Logger _log = Logger.getLogger(TvTManager.class.getName());
/**
* Task for event cycles<br>
*/
private TvTStartTask _task;
/**
* New instance only by getInstance()<br>
*/
protected TvTManager()
{
if (Config.TVT_EVENT_ENABLED)
{
TvTEvent.init();
scheduleEventStart();
_log.info("TvTEventEngine[TvTManager.TvTManager()]: Started.");
}
else
{
_log.info("TvTEventEngine[TvTManager.TvTManager()]: Engine is disabled.");
}
}
/**
* Initialize new/Returns the one and only instance<br>
* <br>
* @return TvTManager<br>
*/
public static TvTManager getInstance()
{
return SingletonHolder._instance;
}
/**
* Starts TvTStartTask
*/
public void scheduleEventStart()
{
try
{
final Calendar currentTime = Calendar.getInstance();
Calendar nextStartTime = null;
Calendar testStartTime = null;
for (String timeOfDay : Config.TVT_EVENT_INTERVAL)
{
// Creating a Calendar object from the specified interval value
testStartTime = Calendar.getInstance();
testStartTime.setLenient(true);
final String[] splitTimeOfDay = timeOfDay.split(":");
testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
// If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
{
testStartTime.add(Calendar.DAY_OF_MONTH, 1);
}
// Check for the test date to be the minimum (smallest in the specified list)
if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
{
nextStartTime = testStartTime;
}
}
if (nextStartTime != null)
{
_task = new TvTStartTask(nextStartTime.getTimeInMillis());
ThreadPoolManager.getInstance().executeGeneral(_task);
}
}
catch (Exception e)
{
_log.warning("TvTEventEngine[TvTManager.scheduleEventStart()]: Error figuring out a start time. Check TvTEventInterval in config file.");
}
}
/**
* Method to start participation
*/
public void startReg()
{
if (!TvTEvent.startParticipation())
{
Broadcast.toAllOnlinePlayers("TvT Event: Event was cancelled.");
_log.warning("TvTEventEngine[TvTManager.run()]: Error spawning event npc for participation.");
scheduleEventStart();
}
else
{
Broadcast.toAllOnlinePlayers("TvT Event: Registration opened for " + Config.TVT_EVENT_PARTICIPATION_TIME + " minute(s).");
// schedule registration end
_task.setStartTime(System.currentTimeMillis() + (60000L * Config.TVT_EVENT_PARTICIPATION_TIME));
ThreadPoolManager.getInstance().executeGeneral(_task);
}
}
/**
* Method to start the fight
*/
public void startEvent()
{
if (!TvTEvent.startFight())
{
Broadcast.toAllOnlinePlayers("TvT Event: Event cancelled due to lack of Participation.");
_log.info("TvTEventEngine[TvTManager.run()]: Lack of registration, abort event.");
scheduleEventStart();
}
else
{
TvTEvent.sysMsgToAllParticipants("TvT Event: Teleporting participants to an arena in " + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
_task.setStartTime(System.currentTimeMillis() + (60000L * Config.TVT_EVENT_RUNNING_TIME));
ThreadPoolManager.getInstance().executeGeneral(_task);
}
}
/**
* Method to end the event and reward
*/
public void endEvent()
{
Broadcast.toAllOnlinePlayers(TvTEvent.calculateRewards());
TvTEvent.sysMsgToAllParticipants("TvT Event: Teleporting back to the registration npc in " + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
TvTEvent.stopFight();
scheduleEventStart();
}
public void skipDelay()
{
if (_task.nextRun.cancel(false))
{
_task.setStartTime(System.currentTimeMillis());
ThreadPoolManager.getInstance().executeGeneral(_task);
}
}
/**
* Class for TvT cycles
*/
class TvTStartTask implements Runnable
{
private long _startTime;
public ScheduledFuture<?> nextRun;
public TvTStartTask(long startTime)
{
_startTime = startTime;
}
public void setStartTime(long startTime)
{
_startTime = startTime;
}
@Override
public void run()
{
final int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
if (delay > 0)
{
announce(delay);
}
int nextMsg = 0;
if (delay > 3600)
{
nextMsg = delay - 3600;
}
else if (delay > 1800)
{
nextMsg = delay - 1800;
}
else if (delay > 900)
{
nextMsg = delay - 900;
}
else if (delay > 600)
{
nextMsg = delay - 600;
}
else if (delay > 300)
{
nextMsg = delay - 300;
}
else if (delay > 60)
{
nextMsg = delay - 60;
}
else if (delay > 5)
{
nextMsg = delay - 5;
}
else if (delay > 0)
{
nextMsg = delay;
}
else
{
// start
if (TvTEvent.isInactive())
{
startReg();
}
else if (TvTEvent.isParticipating())
{
startEvent();
}
else
{
endEvent();
}
}
if (delay > 0)
{
nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
}
}
private void announce(long time)
{
if ((time >= 3600) && ((time % 3600) == 0))
{
if (TvTEvent.isParticipating())
{
Broadcast.toAllOnlinePlayers("TvT Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
}
else if (TvTEvent.isStarted())
{
TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
}
}
else if (time >= 60)
{
if (TvTEvent.isParticipating())
{
Broadcast.toAllOnlinePlayers("TvT Event: " + (time / 60) + " minute(s) until registration is closed!");
}
else if (TvTEvent.isStarted())
{
TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60) + " minute(s) until the event is finished!");
}
}
else
{
if (TvTEvent.isParticipating())
{
Broadcast.toAllOnlinePlayers("TvT Event: " + time + " second(s) until registration is closed!");
}
else if (TvTEvent.isStarted())
{
TvTEvent.sysMsgToAllParticipants("TvT Event: " + time + " second(s) until the event is finished!");
}
}
}
}
private static class SingletonHolder
{
protected static final TvTManager _instance = new TvTManager();
}
}

View File

@ -0,0 +1,232 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity.clanhall;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.commons.database.pool.impl.ConnectionFactory;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.instancemanager.ClanHallAuctionManager;
import com.l2jmobius.gameserver.instancemanager.ClanHallManager;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.entity.ClanHall;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
public final class AuctionableHall extends ClanHall
{
protected long _paidUntil;
private final int _grade;
protected boolean _paid;
private final int _lease;
private final int _chRate = 604800000;
public AuctionableHall(StatsSet set)
{
super(set);
_paidUntil = set.getLong("paidUntil");
_grade = set.getInt("grade");
_paid = set.getBoolean("paid");
_lease = set.getInt("lease");
if (getOwnerId() != 0)
{
_isFree = false;
initialyzeTask(false);
loadFunctions();
}
}
/**
* @return if clanHall is paid or not
*/
public final boolean getPaid()
{
return _paid;
}
/** Return lease */
@Override
public final int getLease()
{
return _lease;
}
/** Return PaidUntil */
@Override
public final long getPaidUntil()
{
return _paidUntil;
}
/** Return Grade */
@Override
public final int getGrade()
{
return _grade;
}
@Override
public final void free()
{
super.free();
_paidUntil = 0;
_paid = false;
}
@Override
public final void setOwner(L2Clan clan)
{
super.setOwner(clan);
_paidUntil = System.currentTimeMillis();
initialyzeTask(true);
}
/**
* Initialize Fee Task
* @param forced
*/
private final void initialyzeTask(boolean forced)
{
final long currentTime = System.currentTimeMillis();
if (_paidUntil > currentTime)
{
ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - currentTime);
}
else if (!_paid && !forced)
{
if ((System.currentTimeMillis() + (3600000 * 24)) <= (_paidUntil + _chRate))
{
ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), System.currentTimeMillis() + (3600000 * 24));
}
else
{
ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), (_paidUntil + _chRate) - System.currentTimeMillis());
}
}
else
{
ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), 0);
}
}
/** Fee Task */
protected class FeeTask implements Runnable
{
private final Logger _log = Logger.getLogger(FeeTask.class.getName());
@Override
public void run()
{
try
{
final long _time = System.currentTimeMillis();
if (isFree())
{
return;
}
if (_paidUntil > _time)
{
ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - _time);
return;
}
final L2Clan Clan = ClanTable.getInstance().getClan(getOwnerId());
if (ClanTable.getInstance().getClan(getOwnerId()).getWarehouse().getAdena() >= getLease())
{
if (_paidUntil != 0)
{
while (_paidUntil <= _time)
{
_paidUntil += _chRate;
}
}
else
{
_paidUntil = _time + _chRate;
}
ClanTable.getInstance().getClan(getOwnerId()).getWarehouse().destroyItemByItemId("CH_rental_fee", Inventory.ADENA_ID, getLease(), null, null);
ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - _time);
_paid = true;
updateDb();
}
else
{
_paid = false;
if (_time > (_paidUntil + _chRate))
{
if (ClanHallManager.getInstance().loaded())
{
ClanHallAuctionManager.getInstance().initNPC(getId());
ClanHallManager.getInstance().setFree(getId());
Clan.broadcastToOnlineMembers(SystemMessage.getSystemMessage(SystemMessageId.THE_CLAN_HALL_FEE_IS_ONE_WEEK_OVERDUE));
}
else
{
ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), 3000);
}
}
else
{
updateDb();
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_MAKE_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW);
sm.addInt(getLease());
Clan.broadcastToOnlineMembers(sm);
if ((_time + (3600000 * 24)) <= (_paidUntil + _chRate))
{
ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _time + (3600000 * 24));
}
else
{
ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), (_paidUntil + _chRate) - _time);
}
}
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "", e);
}
}
}
@Override
public final void updateDb()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("UPDATE clanhall SET ownerId=?, paidUntil=?, paid=? WHERE id=?"))
{
ps.setInt(1, getOwnerId());
ps.setLong(2, getPaidUntil());
ps.setInt(3, (getPaid()) ? 1 : 0);
ps.setInt(4, getId());
ps.execute();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Exception: updateOwnerInDB(L2Clan clan): " + e.getMessage(), e);
}
}
}

View File

@ -0,0 +1,515 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity.clanhall;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.pool.impl.ConnectionFactory;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.enums.SiegeClanType;
import com.l2jmobius.gameserver.instancemanager.CHSiegeManager;
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2SiegeClan;
import com.l2jmobius.gameserver.model.L2Spawn;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.entity.Siegable;
import com.l2jmobius.gameserver.model.quest.Quest;
import com.l2jmobius.gameserver.network.NpcStringId;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.NpcSay;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.util.Broadcast;
/**
* @author BiggBoss
*/
public abstract class ClanHallSiegeEngine extends Quest implements Siegable
{
private static final String SQL_LOAD_ATTACKERS = "SELECT attacker_id FROM clanhall_siege_attackers WHERE clanhall_id = ?";
private static final String SQL_SAVE_ATTACKERS = "INSERT INTO clanhall_siege_attackers VALUES (?,?)";
private static final String SQL_LOAD_GUARDS = "SELECT * FROM clanhall_siege_guards WHERE clanHallId = ?";
public static final int FORTRESS_RESSISTANCE = 21;
public static final int DEVASTATED_CASTLE = 34;
public static final int BANDIT_STRONGHOLD = 35;
public static final int RAINBOW_SPRINGS = 62;
public static final int BEAST_FARM = 63;
public static final int FORTRESS_OF_DEAD = 64;
protected final Logger _log;
private final Map<Integer, L2SiegeClan> _attackers = new ConcurrentHashMap<>();
private List<L2Spawn> _guards;
public SiegableHall _hall;
public ScheduledFuture<?> _siegeTask;
public boolean _missionAccomplished = false;
public ClanHallSiegeEngine(String name, String descr, final int hallId)
{
super(-1, name, descr);
_log = Logger.getLogger(getClass().getName());
_hall = CHSiegeManager.getInstance().getSiegableHall(hallId);
_hall.setSiege(this);
_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), _hall.getNextSiegeTime() - System.currentTimeMillis() - 3600000);
_log.config(_hall.getName() + " siege scheduled for " + getSiegeDate().getTime() + ".");
loadAttackers();
}
public void loadAttackers()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(SQL_LOAD_ATTACKERS))
{
ps.setInt(1, _hall.getId());
try (ResultSet rset = ps.executeQuery())
{
while (rset.next())
{
final int id = rset.getInt("attacker_id");
final L2SiegeClan clan = new L2SiegeClan(id, SiegeClanType.ATTACKER);
_attackers.put(id, clan);
}
}
}
catch (Exception e)
{
_log.warning(getName() + ": Could not load siege attackers!");
}
}
public final void saveAttackers()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("DELETE FROM clanhall_siege_attackers WHERE clanhall_id = ?"))
{
ps.setInt(1, _hall.getId());
ps.execute();
if (_attackers.size() > 0)
{
try (PreparedStatement insert = con.prepareStatement(SQL_SAVE_ATTACKERS))
{
for (L2SiegeClan clan : _attackers.values())
{
insert.setInt(1, _hall.getId());
insert.setInt(2, clan.getClanId());
insert.execute();
insert.clearParameters();
}
}
}
_log.config(getName() + ": Successfully saved attackers to database.");
}
catch (Exception e)
{
_log.warning(getName() + ": Couldn't save attacker list!");
}
}
public final void loadGuards()
{
if (_guards == null)
{
_guards = new ArrayList<>();
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(SQL_LOAD_GUARDS))
{
ps.setInt(1, _hall.getId());
try (ResultSet rset = ps.executeQuery())
{
while (rset.next())
{
final L2Spawn spawn = new L2Spawn(rset.getInt("npcId"));
spawn.setX(rset.getInt("x"));
spawn.setY(rset.getInt("y"));
spawn.setZ(rset.getInt("z"));
spawn.setHeading(rset.getInt("heading"));
spawn.setRespawnDelay(rset.getInt("respawnDelay"));
spawn.setAmount(1);
_guards.add(spawn);
}
}
}
catch (Exception e)
{
_log.warning(getName() + ": Couldnt load siege guards!");
}
}
}
private final void spawnSiegeGuards()
{
for (L2Spawn guard : _guards)
{
guard.init();
}
}
private final void unSpawnSiegeGuards()
{
if (_guards != null)
{
for (L2Spawn guard : _guards)
{
guard.stopRespawn();
if (guard.getLastSpawn() != null)
{
guard.getLastSpawn().deleteMe();
}
}
}
}
@Override
public List<L2Npc> getFlag(L2Clan clan)
{
List<L2Npc> result = null;
final L2SiegeClan sClan = getAttackerClan(clan);
if (sClan != null)
{
result = sClan.getFlag();
}
return result;
}
public final Map<Integer, L2SiegeClan> getAttackers()
{
return _attackers;
}
@Override
public boolean checkIsAttacker(L2Clan clan)
{
if (clan == null)
{
return false;
}
return _attackers.containsKey(clan.getId());
}
@Override
public boolean checkIsDefender(L2Clan clan)
{
return false;
}
@Override
public L2SiegeClan getAttackerClan(int clanId)
{
return _attackers.get(clanId);
}
@Override
public L2SiegeClan getAttackerClan(L2Clan clan)
{
return getAttackerClan(clan.getId());
}
@Override
public List<L2SiegeClan> getAttackerClans()
{
return new ArrayList<>(_attackers.values());
}
@Override
public List<L2PcInstance> getAttackersInZone()
{
final List<L2PcInstance> attackers = new ArrayList<>();
for (L2PcInstance pc : _hall.getSiegeZone().getPlayersInside())
{
final L2Clan clan = pc.getClan();
if ((clan != null) && _attackers.containsKey(clan.getId()))
{
attackers.add(pc);
}
}
return attackers;
}
@Override
public L2SiegeClan getDefenderClan(int clanId)
{
return null;
}
@Override
public L2SiegeClan getDefenderClan(L2Clan clan)
{
return null;
}
@Override
public List<L2SiegeClan> getDefenderClans()
{
return null;
}
public void prepareOwner()
{
if (_hall.getOwnerId() > 0)
{
final L2SiegeClan clan = new L2SiegeClan(_hall.getOwnerId(), SiegeClanType.ATTACKER);
_attackers.put(clan.getClanId(), new L2SiegeClan(clan.getClanId(), SiegeClanType.ATTACKER));
}
_hall.free();
_hall.banishForeigners();
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.THE_REGISTRATION_TERM_FOR_S1_HAS_ENDED);
msg.addString(getName());
Broadcast.toAllOnlinePlayers(msg);
_hall.updateSiegeStatus(SiegeStatus.WAITING_BATTLE);
_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new SiegeStarts(), 3600000);
}
@Override
public void startSiege()
{
if ((_attackers.size() < 1) && (_hall.getId() != 21)) // Fortress of resistance don't have attacker list
{
onSiegeEnds();
_attackers.clear();
_hall.updateNextSiege();
_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), _hall.getSiegeDate().getTimeInMillis());
_hall.updateSiegeStatus(SiegeStatus.WAITING_BATTLE);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.THE_SIEGE_OF_S1_HAS_BEEN_CANCELED_DUE_TO_LACK_OF_INTEREST);
sm.addString(_hall.getName());
Broadcast.toAllOnlinePlayers(sm);
return;
}
_hall.spawnDoor();
loadGuards();
spawnSiegeGuards();
_hall.updateSiegeZone(true);
final byte state = 1;
for (L2SiegeClan sClan : _attackers.values())
{
final L2Clan clan = ClanTable.getInstance().getClan(sClan.getClanId());
if (clan == null)
{
continue;
}
for (L2PcInstance pc : clan.getOnlineMembers(0))
{
pc.setSiegeState(state);
pc.broadcastUserInfo();
pc.setIsInHideoutSiege(true);
}
}
_hall.updateSiegeStatus(SiegeStatus.RUNNING);
onSiegeStarts();
_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new SiegeEnds(), _hall.getSiegeLenght());
}
@Override
public void endSiege()
{
final SystemMessage end = SystemMessage.getSystemMessage(SystemMessageId.THE_S1_SIEGE_HAS_FINISHED);
end.addString(_hall.getName());
Broadcast.toAllOnlinePlayers(end);
final L2Clan winner = getWinner();
SystemMessage finalMsg = null;
if (_missionAccomplished && (winner != null))
{
_hall.setOwner(winner);
winner.setHideoutId(_hall.getId());
finalMsg = SystemMessage.getSystemMessage(SystemMessageId.CLAN_S1_IS_VICTORIOUS_OVER_S2_S_CASTLE_SIEGE);
finalMsg.addString(winner.getName());
finalMsg.addString(_hall.getName());
Broadcast.toAllOnlinePlayers(finalMsg);
}
else
{
finalMsg = SystemMessage.getSystemMessage(SystemMessageId.THE_SIEGE_OF_S1_HAS_ENDED_IN_A_DRAW);
finalMsg.addString(_hall.getName());
Broadcast.toAllOnlinePlayers(finalMsg);
}
_missionAccomplished = false;
_hall.updateSiegeZone(false);
_hall.updateNextSiege();
_hall.spawnDoor(false);
_hall.banishForeigners();
final byte state = 0;
for (L2SiegeClan sClan : _attackers.values())
{
final L2Clan clan = ClanTable.getInstance().getClan(sClan.getClanId());
if (clan == null)
{
continue;
}
for (L2PcInstance player : clan.getOnlineMembers(0))
{
player.setSiegeState(state);
player.broadcastUserInfo();
player.setIsInHideoutSiege(false);
}
}
// Update pvp flag for winners when siege zone becomes inactive
for (L2Character chr : _hall.getSiegeZone().getCharactersInside())
{
if ((chr != null) && chr.isPlayer())
{
chr.getActingPlayer().startPvPFlag();
}
}
_attackers.clear();
onSiegeEnds();
_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), _hall.getNextSiegeTime() - System.currentTimeMillis() - 3600000);
_log.config("Siege of " + _hall.getName() + " scheduled for " + _hall.getSiegeDate().getTime() + ".");
_hall.updateSiegeStatus(SiegeStatus.REGISTERING);
unSpawnSiegeGuards();
}
@Override
public void updateSiege()
{
cancelSiegeTask();
_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), _hall.getNextSiegeTime() - 3600000);
_log.config(_hall.getName() + " siege scheduled for " + _hall.getSiegeDate().getTime().toString() + ".");
}
public void cancelSiegeTask()
{
if (_siegeTask != null)
{
_siegeTask.cancel(false);
}
}
@Override
public Calendar getSiegeDate()
{
return _hall.getSiegeDate();
}
@Override
public boolean giveFame()
{
return Config.CHS_ENABLE_FAME;
}
@Override
public int getFameAmount()
{
return Config.CHS_FAME_AMOUNT;
}
@Override
public int getFameFrequency()
{
return Config.CHS_FAME_FREQUENCY;
}
public final void broadcastNpcSay(final L2Npc npc, final ChatType type, final NpcStringId messageId)
{
final NpcSay npcSay = new NpcSay(npc.getObjectId(), type, npc.getId(), messageId);
final int sourceRegion = MapRegionManager.getInstance().getMapRegionLocId(npc);
for (L2PcInstance pc : L2World.getInstance().getPlayers())
{
if ((pc != null) && (MapRegionManager.getInstance().getMapRegionLocId(pc) == sourceRegion))
{
pc.sendPacket(npcSay);
}
}
}
public Location getInnerSpawnLoc(L2PcInstance player)
{
return null;
}
public boolean canPlantFlag()
{
return true;
}
public boolean doorIsAutoAttackable()
{
return true;
}
public void onSiegeStarts()
{
}
public void onSiegeEnds()
{
}
public abstract L2Clan getWinner();
public class PrepareOwner implements Runnable
{
@Override
public void run()
{
prepareOwner();
}
}
public class SiegeStarts implements Runnable
{
@Override
public void run()
{
startSiege();
}
}
public class SiegeEnds implements Runnable
{
@Override
public void run()
{
endSiege();
}
}
}

View File

@ -0,0 +1,278 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity.clanhall;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Calendar;
import java.util.logging.Level;
import com.l2jmobius.commons.database.pool.impl.ConnectionFactory;
import com.l2jmobius.gameserver.enums.SiegeClanType;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2SiegeClan;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.entity.ClanHall;
import com.l2jmobius.gameserver.model.zone.type.L2SiegableHallZone;
import com.l2jmobius.gameserver.model.zone.type.L2SiegeZone;
import com.l2jmobius.gameserver.network.serverpackets.SiegeInfo;
/**
* @author BiggBoss
*/
public final class SiegableHall extends ClanHall
{
private static final String SQL_SAVE = "UPDATE siegable_clanhall SET ownerId=?, nextSiege=? WHERE clanHallId=?";
private Calendar _nextSiege;
private final long _siegeLength;
private final int[] _scheduleConfig =
{
7,
0,
0,
12,
0
};
private SiegeStatus _status = SiegeStatus.REGISTERING;
private L2SiegeZone _siegeZone;
private ClanHallSiegeEngine _siege;
public SiegableHall(StatsSet set)
{
super(set);
_siegeLength = set.getLong("siegeLenght");
final String[] rawSchConfig = set.getString("scheduleConfig").split(";");
if (rawSchConfig.length == 5)
{
for (int i = 0; i < 5; i++)
{
try
{
_scheduleConfig[i] = Integer.parseInt(rawSchConfig[i]);
}
catch (Exception e)
{
_log.warning("SiegableHall - " + getName() + ": Wrong schedule_config parameters!");
}
}
}
else
{
_log.warning(getName() + ": Wrong schedule_config value in siegable_halls table, using default (7 days)");
}
_nextSiege = Calendar.getInstance();
final long nextSiege = set.getLong("nextSiege");
if ((nextSiege - System.currentTimeMillis()) < 0)
{
updateNextSiege();
}
else
{
_nextSiege.setTimeInMillis(nextSiege);
}
if (getOwnerId() != 0)
{
_isFree = false;
loadFunctions();
}
}
public void spawnDoor()
{
spawnDoor(false);
}
public void spawnDoor(boolean isDoorWeak)
{
for (L2DoorInstance door : getDoors())
{
if (door.isDead())
{
door.doRevive();
if (isDoorWeak)
{
door.setCurrentHp(door.getMaxHp() / 2);
}
else
{
door.setCurrentHp(door.getMaxHp());
}
}
if (door.getOpen())
{
door.closeMe();
}
}
}
@Override
public final void updateDb()
{
try (Connection con = ConnectionFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(SQL_SAVE))
{
ps.setInt(1, getOwnerId());
ps.setLong(2, getNextSiegeTime());
ps.setInt(3, getId());
ps.execute();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Exception: SiegableHall.updateDb(): " + e.getMessage(), e);
}
}
public final void setSiege(final ClanHallSiegeEngine siegable)
{
_siege = siegable;
_siegeZone.setSiegeInstance(siegable);
}
public final ClanHallSiegeEngine getSiege()
{
return _siege;
}
public final Calendar getSiegeDate()
{
return _nextSiege;
}
public final long getNextSiegeTime()
{
return _nextSiege.getTimeInMillis();
}
public long getSiegeLenght()
{
return _siegeLength;
}
public final void setNextSiegeDate(long date)
{
_nextSiege.setTimeInMillis(date);
}
public final void setNextSiegeDate(final Calendar c)
{
_nextSiege = c;
}
public final void updateNextSiege()
{
final Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_YEAR, _scheduleConfig[0]);
c.add(Calendar.MONTH, _scheduleConfig[1]);
c.add(Calendar.YEAR, _scheduleConfig[2]);
c.set(Calendar.HOUR_OF_DAY, _scheduleConfig[3]);
c.set(Calendar.MINUTE, _scheduleConfig[4]);
c.set(Calendar.SECOND, 0);
setNextSiegeDate(c);
updateDb();
}
public final void addAttacker(final L2Clan clan)
{
if (getSiege() != null)
{
getSiege().getAttackers().put(clan.getId(), new L2SiegeClan(clan.getId(), SiegeClanType.ATTACKER));
}
}
public final void removeAttacker(final L2Clan clan)
{
if (getSiege() != null)
{
getSiege().getAttackers().remove(clan.getId());
}
}
public final boolean isRegistered(L2Clan clan)
{
if (getSiege() == null)
{
return false;
}
return getSiege().checkIsAttacker(clan);
}
public SiegeStatus getSiegeStatus()
{
return _status;
}
public final boolean isRegistering()
{
return _status == SiegeStatus.REGISTERING;
}
public final boolean isInSiege()
{
return _status == SiegeStatus.RUNNING;
}
public final boolean isWaitingBattle()
{
return _status == SiegeStatus.WAITING_BATTLE;
}
public final void updateSiegeStatus(SiegeStatus status)
{
_status = status;
}
public final L2SiegeZone getSiegeZone()
{
return _siegeZone;
}
public final void setSiegeZone(L2SiegeZone zone)
{
_siegeZone = zone;
}
public final void updateSiegeZone(boolean active)
{
_siegeZone.setIsActive(active);
}
public final void showSiegeInfo(L2PcInstance player)
{
player.sendPacket(new SiegeInfo(this));
}
@Override
public final boolean isSiegableHall()
{
return true;
}
@Override
public L2SiegableHallZone getZone()
{
return (L2SiegableHallZone) super.getZone();
}
}

View File

@ -0,0 +1,27 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.entity.clanhall;
/**
* @author BiggBoss
*/
public enum SiegeStatus
{
REGISTERING,
WAITING_BATTLE,
RUNNING
}