l2j_mobius/trunk/java/com/l2jmobius/gameserver/model/entity/ClanHall.java
2016-06-12 01:34:09 +00:00

388 lines
11 KiB
Java

/*
* 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.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.data.xml.impl.ClanHallData;
import com.l2jmobius.gameserver.enums.ClanHallGrade;
import com.l2jmobius.gameserver.enums.ClanHallType;
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.holders.ClanHallTeleportHolder;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.residences.AbstractResidence;
import com.l2jmobius.gameserver.model.zone.type.L2ClanHallZone;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.PledgeShowInfoUpdate;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/**
* @author St3eT
*/
public final class ClanHall extends AbstractResidence
{
// Static parameters
private final ClanHallGrade _grade;
private final ClanHallType _type;
private final int _minBid;
private final int _lease;
private final int _deposit;
private final List<Integer> _npcs;
private final List<L2DoorInstance> _doors;
private final List<ClanHallTeleportHolder> _teleports;
private final Location _ownerLocation;
private final Location _banishLocation;
// Dynamic parameters
private L2Clan _owner = null;
private long _paidUntil = 0;
protected ScheduledFuture<?> _checkPaymentTask = null;
// Other
private static final String INSERT_CLANHALL = "INSERT INTO clanhall (id, ownerId, paidUntil) VALUES (?,?,?)";
private static final String LOAD_CLANHALL = "SELECT * FROM clanhall WHERE id=?";
private static final String UPDATE_CLANHALL = "UPDATE clanhall SET ownerId=?,paidUntil=? WHERE id=?";
private static final Logger LOGGER = Logger.getLogger(ClanHallData.class.getName());
public ClanHall(StatsSet params)
{
super(params.getInt("id"));
// Set static parameters
setName(params.getString("name"));
_grade = params.getEnum("grade", ClanHallGrade.class);
_type = params.getEnum("type", ClanHallType.class);
_minBid = params.getInt("minBid");
_lease = params.getInt("lease");
_deposit = params.getInt("deposit");
_npcs = params.getList("npcList", Integer.class);
_doors = params.getList("doorList", L2DoorInstance.class);
_teleports = params.getList("teleportList", ClanHallTeleportHolder.class);
_ownerLocation = params.getLocation("owner_loc");
_banishLocation = params.getLocation("banish_loc");
// Set dynamic parameters (from DB)
load();
// Init Clan Hall zone and Functions
initResidenceZone();
initFunctions();
}
@Override
protected void load()
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement loadStatement = con.prepareStatement(LOAD_CLANHALL);
PreparedStatement insertStatement = con.prepareStatement(INSERT_CLANHALL))
{
loadStatement.setInt(1, getResidenceId());
try (ResultSet rset = loadStatement.executeQuery())
{
if (rset.next())
{
setPaidUntil(rset.getLong("paidUntil"));
setOwner(rset.getInt("ownerId"));
}
else
{
insertStatement.setInt(1, getResidenceId());
insertStatement.setInt(2, 0); // New clanhall should not have owner
insertStatement.setInt(3, 0); // New clanhall should not have paid until
if (insertStatement.execute())
{
LOGGER.info("Clan Hall " + getName() + " (" + getResidenceId() + ") was sucessfully created.");
}
}
}
}
catch (SQLException e)
{
LOGGER.log(Level.INFO, "Failed loading clan hall", e);
}
}
public void updateDB()
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement(UPDATE_CLANHALL))
{
statement.setInt(1, getOwnerId());
statement.setLong(2, getPaidUntil());
statement.setInt(3, getResidenceId());
statement.execute();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
@Override
protected void initResidenceZone()
{
final L2ClanHallZone zone = ZoneManager.getInstance().getAllZones(L2ClanHallZone.class).stream().filter(z -> z.getResidenceId() == getResidenceId()).findFirst().orElse(null);
if (zone != null)
{
setResidenceZone(zone);
}
}
public int getCostFailDay()
{
final Duration failDay = Duration.between(Instant.ofEpochMilli(getPaidUntil()), Instant.now());
return failDay.isNegative() ? 0 : (int) failDay.toDays();
}
/**
* Teleport all non-owner players from {@link L2ClanHallZone} to {@link ClanHall#getBanishLocation()}.
*/
public void banishOthers()
{
getResidenceZone().banishForeigners(getOwnerId());
}
/**
* Open or close all {@link L2DoorInstance} related to this {@link ClanHall}.
* @param open {@code true} means open door, {@code false} means close door
*/
public void openCloseDoors(boolean open)
{
_doors.forEach(door -> door.openCloseMe(open));
}
/**
* Gets the grade of clan hall.
* @return grade of this {@link ClanHall} in {@link ClanHallGrade} enum.
*/
public ClanHallGrade getGrade()
{
return _grade;
}
/**
* Gets all {@link L2DoorInstance} related to this {@link ClanHall}.
* @return all {@link L2DoorInstance} related to this {@link ClanHall}
*/
public List<L2DoorInstance> getDoors()
{
return _doors;
}
/**
* Gets all {@link L2Npc} related to this {@link ClanHall}.
* @return all {@link L2Npc} related to this {@link ClanHall}
*/
public List<Integer> getNpcs()
{
return _npcs;
}
/**
* Gets the {@link ClanHallType} of this {@link ClanHall}.
* @return {@link ClanHallType} of this {@link ClanHall} in {@link ClanHallGrade} enum.
*/
public ClanHallType getType()
{
return _type;
}
/**
* Gets the {@link L2Clan} which own this {@link ClanHall}.
* @return {@link L2Clan} which own this {@link ClanHall}
*/
public L2Clan getOwner()
{
return _owner;
}
/**
* Gets the {@link L2Clan} ID which own this {@link ClanHall}.
* @return the {@link L2Clan} ID which own this {@link ClanHall}
*/
@Override
public int getOwnerId()
{
final L2Clan owner = _owner;
return (owner != null) ? owner.getId() : 0;
}
/**
* Set the owner of clan hall
* @param clanId the Id of the clan
*/
public void setOwner(int clanId)
{
setOwner(ClanTable.getInstance().getClan(clanId));
}
/**
* Set the clan as owner of clan hall
* @param clan the L2Clan object
*/
public void setOwner(L2Clan clan)
{
if (clan != null)
{
_owner = clan;
clan.setHideoutId(getResidenceId());
clan.broadcastToOnlineMembers(new PledgeShowInfoUpdate(clan));
if (getPaidUntil() == 0)
{
setPaidUntil(Instant.now().plus(Duration.ofDays(7)).toEpochMilli());
}
final int failDays = getCostFailDay();
final long time = failDays > 0 ? (failDays > 8 ? Instant.now().toEpochMilli() : Instant.ofEpochMilli(getPaidUntil()).plus(Duration.ofDays(failDays + 1)).toEpochMilli()) : getPaidUntil();
_checkPaymentTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckPaymentTask(), time - System.currentTimeMillis());
}
else
{
if (_owner != null)
{
_owner.setHideoutId(0);
_owner.broadcastToOnlineMembers(new PledgeShowInfoUpdate(_owner));
removeFunctions();
}
_owner = null;
setPaidUntil(0);
if (_checkPaymentTask != null)
{
_checkPaymentTask.cancel(true);
_checkPaymentTask = null;
}
}
updateDB();
}
/**
* Gets the due date of clan hall payment
* @return the due date of clan hall payment
*/
public long getPaidUntil()
{
return _paidUntil;
}
/**
* Set the due date of clan hall payment
* @param paidUntil the due date of clan hall payment
*/
public void setPaidUntil(long paidUntil)
{
_paidUntil = paidUntil;
}
/**
* Gets the next date of clan hall payment
* @return the next date of clan hall payment
*/
public long getNextPayment()
{
return (_checkPaymentTask != null) ? System.currentTimeMillis() + _checkPaymentTask.getDelay(TimeUnit.MILLISECONDS) : 0;
}
public Location getOwnerLocation()
{
return _ownerLocation;
}
public Location getBanishLocation()
{
return _banishLocation;
}
public List<ClanHallTeleportHolder> getTeleportList()
{
return _teleports;
}
public List<ClanHallTeleportHolder> getTeleportList(int functionLevel)
{
return _teleports.stream().filter(holder -> holder.getMinFunctionLevel() <= functionLevel).collect(Collectors.toList());
}
public int getMinBid()
{
return _minBid;
}
public int getLease()
{
return _lease;
}
public int getDeposit()
{
return _deposit;
}
class CheckPaymentTask implements Runnable
{
@Override
public void run()
{
final L2Clan clan = getOwner();
if (clan != null)
{
if (clan.getWarehouse().getAdena() < getLease())
{
if (getCostFailDay() > 8)
{
setOwner(null);
clan.broadcastToOnlineMembers(SystemMessage.getSystemMessage(SystemMessageId.THE_CLAN_HALL_FEE_IS_ONE_WEEK_OVERDUE_THEREFORE_THE_CLAN_HALL_OWNERSHIP_HAS_BEEN_REVOKED));
}
else
{
_checkPaymentTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckPaymentTask(), 1, TimeUnit.DAYS);
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);
}
}
else
{
clan.getWarehouse().destroyItem("Clan Hall Lease", Inventory.ADENA_ID, getLease(), null, null);
setPaidUntil(Instant.ofEpochMilli(getPaidUntil()).plus(Duration.ofDays(7)).toEpochMilli());
_checkPaymentTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckPaymentTask(), getPaidUntil() - System.currentTimeMillis());
updateDB();
}
}
}
}
@Override
public String toString()
{
return (getClass().getSimpleName() + ":" + getName() + "[" + getResidenceId() + "]");
}
}