Addition of attendance system.

This commit is contained in:
MobiusDev 2018-03-05 16:01:14 +00:00
parent 364cd8d6b2
commit 6242181e3f
64 changed files with 2421 additions and 12 deletions

View File

@ -0,0 +1,26 @@
# ---------------------------------------------------------------------------
# Attendance Reward Settings
# ---------------------------------------------------------------------------
# Enable daily login rewards for players.
# To enable this feature you need to set L2.ini UseVIPAttendance value to true.
# Rewards are set at data\AttendanceRewards.xml file.
# Enable the Attendance Reward system.
# Default: False
EnableAttendanceRewards = False
# Enable the Attendance Reward system only for Premium accounts.
# Default: False
PremiumOnlyAttendanceRewards = False
# Make rewards sharable in the same account.
# Default: False (Each character will receive its own rewards.)
AttendanceRewardsShareAccount = False
# Time in minutes you can redeem your reward after logging in.
# Retail: 30
AttendanceRewardDelay = 30
# Popup the reward window if reward is available 30 minutes after login.
# Default: False
AttendancePopupWindow = False

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/AttendanceRewards.xsd">
<item id="23805" count="50" /> <!-- Hero Coin -->
<item id="22610" count="3" /> <!-- Luxury Cocktail -->
<item id="1540" count="10" /> <!-- Quick Healing Potion -->
<item id="22979" count="3" /> <!-- SP Rune 50% (1-hour) -->
<item id="22906" count="3" /> <!-- XP Rune III 50% (1-hour) -->
<item id="20353" count="10" /> <!-- Greater CP Potion -->
<item id="21343" count="1" /> <!-- Agathion - Cow (7-Day) -->
<item id="23805" count="100" /> <!-- Hero Coin -->
<item id="22610" count="3" /> <!-- Luxury Cocktail -->
<item id="1540" count="10" /> <!-- Quick Healing Potion -->
<item id="22979" count="3" /> <!-- SP Rune 50% (1-hour) -->
<item id="22906" count="3" /> <!-- XP Rune III 50% (1-hour) -->
<item id="20353" count="10" /> <!-- Greater CP Potion -->
<item id="21331" count="1" /> <!-- Agathion - Griffin (7-Day) -->
<item id="23805" count="150" /> <!-- Hero Coin -->
<item id="22610" count="6" /> <!-- Luxury Cocktail -->
<item id="1540" count="20" /> <!-- Quick Healing Potion -->
<item id="22979" count="5" /> <!-- SP Rune 50% (1-hour) -->
<item id="22906" count="5" /> <!-- XP Rune III 50% (1-hour) -->
<item id="20353" count="20" /> <!-- Greater CP Potion -->
<item id="21166" count="1" /> <!-- Agathion - Zaken's Spirit Swords (7-Day) -->
<item id="23805" count="300" /> <!-- Hero Coin -->
<item id="22610" count="6" /> <!-- Luxury Cocktail -->
<item id="1540" count="20" /> <!-- Quick Healing Potion -->
<item id="23284" count="5" /> <!-- SP Rune 100% (1-hour) -->
<item id="23277" count="5" /> <!-- XP Rune III 100% (1-hour) -->
<item id="23176" count="1" /> <!-- Stylish Straw Hat (30-Day) -->
<item id="22955" count="1" /> <!-- Mount - Tame Princess Ant (30-Day) -->
</list>

View File

@ -28,6 +28,7 @@ import com.l2jmobius.gameserver.data.xml.impl.AbilityPointsData;
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AppearanceItemData;
import com.l2jmobius.gameserver.data.xml.impl.ArmorSetsData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
import com.l2jmobius.gameserver.data.xml.impl.EnchantItemData;
@ -305,6 +306,12 @@ public class AdminReload implements IAdminCommandHandler
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Fishing data.");
break;
}
case "attendance":
{
AttendanceRewardData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Attendance Reward data.");
break;
}
case "fakeplayers":
{
FakePlayerData.getInstance().load();

View File

@ -0,0 +1,18 @@
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element name="item" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:int" name="id" use="required"/>
<xs:attribute type="xs:int" name="count" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -81,6 +81,7 @@ public final class Config
// --------------------------------------------------
// Config File Definitions
// --------------------------------------------------
public static final String ATTENDANCE_CONFIG_FILE = "./config/AttendanceRewards.ini";
public static final String CHARACTER_CONFIG_FILE = "./config/Character.ini";
public static final String CH_SIEGE_CONFIG_FILE = "./config/ConquerableHallSiege.ini";
public static final String FEATURE_CONFIG_FILE = "./config/Feature.ini";
@ -137,6 +138,11 @@ public final class Config
// --------------------------------------------------
// Variable Definitions
// --------------------------------------------------
public static boolean ENABLE_ATTENDANCE_REWARDS;
public static boolean PREMIUM_ONLY_ATTENDANCE_REWARDS;
public static boolean ATTENDANCE_REWARDS_SHARE_ACCOUNT;
public static int ATTENDANCE_REWARD_DELAY;
public static boolean ATTENDANCE_POPUP_WINDOW;
public static boolean PLAYER_DELEVEL;
public static int DELEVEL_MINIMUM;
public static boolean DECREASE_SKILL_LEVEL;
@ -1416,6 +1422,14 @@ public final class Config
ALLOW_WYVERN_ALWAYS = Feature.getBoolean("AllowRideWyvernAlways", false);
ALLOW_WYVERN_DURING_SIEGE = Feature.getBoolean("AllowRideWyvernDuringSiege", true);
// Load Attandance config file (if exists)
final PropertiesParser Attandance = new PropertiesParser(ATTENDANCE_CONFIG_FILE);
ENABLE_ATTENDANCE_REWARDS = Attandance.getBoolean("EnableAttendanceRewards", false);
PREMIUM_ONLY_ATTENDANCE_REWARDS = Attandance.getBoolean("PremiumOnlyAttendanceRewards", false);
ATTENDANCE_REWARDS_SHARE_ACCOUNT = Attandance.getBoolean("AttendanceRewardsShareAccount", false);
ATTENDANCE_REWARD_DELAY = Attandance.getInt("AttendanceRewardDelay", 30);
ATTENDANCE_POPUP_WINDOW = Attandance.getBoolean("AttendancePopupWindow", false);
// Load Character config file (if exists)
final PropertiesParser Character = new PropertiesParser(CHARACTER_CONFIG_FILE);

View File

@ -44,6 +44,7 @@ import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AlchemyData;
import com.l2jmobius.gameserver.data.xml.impl.AppearanceItemData;
import com.l2jmobius.gameserver.data.xml.impl.ArmorSetsData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.BeautyShopData;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.data.xml.impl.CategoryData;
@ -244,6 +245,7 @@ public class GameServer
AlchemyData.getInstance();
CommissionManager.getInstance();
LuckyGameData.getInstance();
AttendanceRewardData.getInstance();
printSection("Characters");
ClassListData.getInstance();

View File

@ -0,0 +1,100 @@
/*
* 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.data.xml.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.IGameXmlReader;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
/**
* @author Mobius
*/
public class AttendanceRewardData implements IGameXmlReader
{
private static Logger LOGGER = Logger.getLogger(AttendanceRewardData.class.getName());
private final List<ItemHolder> _rewards = new ArrayList<>();
private int _rewardsCount = 0;
protected AttendanceRewardData()
{
load();
}
@Override
public void load()
{
if (Config.ENABLE_ATTENDANCE_REWARDS)
{
getRewards().clear();
parseDatapackFile("data/AttendanceRewards.xml");
_rewardsCount = getRewards().size();
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _rewardsCount + " rewards.");
}
else
{
LOGGER.info(getClass().getSimpleName() + ": Disabled.");
}
}
@Override
public void parseDocument(Document doc, File f)
{
forEach(doc, "list", listNode -> forEach(listNode, "item", rewardNode ->
{
final StatsSet set = new StatsSet(parseAttributes(rewardNode));
final int itemId = set.getInt("id");
final int itemCount = set.getInt("count");
if (ItemTable.getInstance().getTemplate(itemId) == null)
{
LOGGER.info(getClass().getSimpleName() + ": Item with id " + itemId + " does not exist.");
}
else
{
getRewards().add(new ItemHolder(itemId, itemCount));
}
}));
}
public List<ItemHolder> getRewards()
{
return _rewards;
}
public int getRewardsCount()
{
return _rewardsCount;
}
public static AttendanceRewardData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final AttendanceRewardData _instance = new AttendanceRewardData();
}
}

View File

@ -63,6 +63,7 @@ import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
import com.l2jmobius.gameserver.data.sql.impl.CharSummonTable;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.ClassListData;
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import com.l2jmobius.gameserver.data.xml.impl.HennaData;
@ -207,6 +208,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerPvPCh
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerPvPKill;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerReputationChanged;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerSubChange;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.holders.MovieHolder;
import com.l2jmobius.gameserver.model.holders.PlayerEventHolder;
@ -845,6 +847,10 @@ public final class L2PcInstance extends L2Playable
private final static String TRAINING_CAMP_VAR = "TRAINING_CAMP";
private final static String TRAINING_CAMP_DURATION = "TRAINING_CAMP_DURATION";
// Attendance Reward system
private final static String ATTENDANCE_DATE_VAR = "ATTENDANCE_DATE";
private final static String ATTENDANCE_INDEX_VAR = "ATTENDANCE_INDEX";
// Save responder name for log it
private String _lastPetitionGmName = null;
@ -14053,4 +14059,60 @@ public final class L2PcInstance extends L2Playable
final TrainingHolder trainingHolder = getTraingCampInfo();
return (trainingHolder != null) && (trainingHolder.getEndTime() > 0);
}
public AttendanceInfoHolder getAttendanceInfo()
{
// Get reset time.
final Calendar calendar = Calendar.getInstance();
if ((calendar.get(Calendar.HOUR_OF_DAY) < 6) && (calendar.get(Calendar.MINUTE) < 30))
{
calendar.add(Calendar.DAY_OF_MONTH, -1);
}
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// Get last player reward time.
final long receiveDate;
int rewardIndex;
if (Config.ATTENDANCE_REWARDS_SHARE_ACCOUNT)
{
receiveDate = getAccountVariables().getLong(ATTENDANCE_DATE_VAR, 0);
rewardIndex = getAccountVariables().getInt(ATTENDANCE_INDEX_VAR, 0);
}
else
{
receiveDate = getVariables().getLong(ATTENDANCE_DATE_VAR, 0);
rewardIndex = getVariables().getInt(ATTENDANCE_INDEX_VAR, 0);
}
// Check if player can receive reward today.
boolean canBeRewarded = false;
if (calendar.getTimeInMillis() > receiveDate)
{
canBeRewarded = true;
// Reset index if max is reached.
if (rewardIndex >= AttendanceRewardData.getInstance().getRewardsCount())
{
rewardIndex = 0;
}
}
return new AttendanceInfoHolder(rewardIndex, canBeRewarded);
}
public void setAttendanceInfo(int rewardIndex)
{
if (Config.ATTENDANCE_REWARDS_SHARE_ACCOUNT)
{
getAccountVariables().set(ATTENDANCE_DATE_VAR, System.currentTimeMillis());
getAccountVariables().set(ATTENDANCE_INDEX_VAR, rewardIndex);
}
else
{
getVariables().set(ATTENDANCE_DATE_VAR, System.currentTimeMillis());
getVariables().set(ATTENDANCE_INDEX_VAR, rewardIndex);
}
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.holders;
/**
* @author Mobius
*/
public class AttendanceInfoHolder
{
private final int _rewardIndex;
private final boolean _rewardAvailable;
public AttendanceInfoHolder(int rewardIndex, boolean rewardAvailable)
{
_rewardIndex = rewardIndex;
_rewardAvailable = rewardAvailable;
}
public int getRewardIndex()
{
return _rewardIndex;
}
public boolean isRewardAvailable()
{
return _rewardAvailable;
}
}

View File

@ -40,6 +40,8 @@ import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExCancel
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExTryToPutShapeShiftingEnchantSupportItem;
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExTryToPutShapeShiftingTargetItem;
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestShapeShiftingItem;
import com.l2jmobius.gameserver.network.clientpackets.attendance.RequestVipAttendanceCheck;
import com.l2jmobius.gameserver.network.clientpackets.attendance.RequestVipAttendanceItemList;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.RequestChangeAttributeCancel;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.RequestChangeAttributeItem;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.SendChangeAttributeTargetItem;
@ -348,8 +350,8 @@ public enum ExIncomingPackets implements IIncomingPackets<L2GameClient>
SEND_EXECUTED_UI_EVENTS_COUNT(0x102, null, ConnectionState.IN_GAME),
EX_SEND_CLIENT_INI(0x103, null, ConnectionState.IN_GAME),
REQUEST_EX_AUTO_FISH(0x104, ExRequestAutoFish::new, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_ITEM_LIST(0x105, null, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_CHECK(0x106, null, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_ITEM_LIST(0x105, RequestVipAttendanceItemList::new, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_CHECK(0x106, RequestVipAttendanceCheck::new, ConnectionState.IN_GAME),
REQUEST_ITEM_ENSOUL(0x107, RequestItemEnsoul::new, ConnectionState.IN_GAME),
REQUEST_VIP_PRODUCT_LIST(0x108, null, ConnectionState.IN_GAME),
REQUEST_VIP_LUCKY_GAME_INFO(0x109, null, ConnectionState.IN_GAME),

View File

@ -51,6 +51,7 @@ import com.l2jmobius.gameserver.model.entity.Fort;
import com.l2jmobius.gameserver.model.entity.FortSiege;
import com.l2jmobius.gameserver.model.entity.L2Event;
import com.l2jmobius.gameserver.model.entity.Siege;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.instancezone.Instance;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.quest.Quest;
@ -98,6 +99,7 @@ import com.l2jmobius.gameserver.network.serverpackets.SkillCoolTime;
import com.l2jmobius.gameserver.network.serverpackets.SkillList;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.ability.ExAcquireAPSkillList;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList;
import com.l2jmobius.gameserver.network.serverpackets.dailymission.ExOneDayReceiveRewardList;
import com.l2jmobius.gameserver.network.serverpackets.friend.L2FriendList;
@ -653,6 +655,26 @@ public class EnterWorld implements IClientIncomingPacket
activeChar.updateAbnormalVisualEffects();
}
if (Config.ENABLE_ATTENDANCE_REWARDS)
{
ThreadPoolManager.schedule(() ->
{
// Check if player can receive reward today.
final AttendanceInfoHolder attendanceInfo = activeChar.getAttendanceInfo();
if (attendanceInfo.isRewardAvailable())
{
final int lastRewardIndex = attendanceInfo.getRewardIndex() + 1;
activeChar.sendPacket(new ExShowScreenMessage("Your attendance day " + lastRewardIndex + " reward is ready.", ExShowScreenMessage.TOP_CENTER, 7000, 0, true, true));
activeChar.sendMessage("Your attendance day " + lastRewardIndex + " reward is ready.");
activeChar.sendMessage("Click on General Menu -> Attendance Check.");
if (Config.ATTENDANCE_POPUP_WINDOW)
{
activeChar.sendPacket(new ExVipAttendanceItemList(activeChar));
}
}
}, Config.ATTENDANCE_REWARD_DELAY * 60 * 1000);
}
if (Config.HARDWARE_INFO_ENABLED)
{
ThreadPoolManager.schedule(() ->

View File

@ -0,0 +1,103 @@
/*
* 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.network.clientpackets.attendance;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExConfirmVipAttendanceCheck;
/**
* @author Mobius
*/
public class RequestVipAttendanceCheck implements IClientIncomingPacket
{
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(L2GameClient client)
{
final L2PcInstance activeChar = client.getActiveChar();
if (activeChar == null)
{
return;
}
if (!Config.ENABLE_ATTENDANCE_REWARDS)
{
activeChar.sendPacket(SystemMessageId.DUE_TO_A_SYSTEM_ERROR_THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_PLEASE_TRY_AGAIN_LATER_BY_GOING_TO_MENU_ATTENDANCE_CHECK);
return;
}
if (Config.PREMIUM_ONLY_ATTENDANCE_REWARDS && !activeChar.hasPremiumStatus())
{
activeChar.sendPacket(SystemMessageId.YOUR_VIP_RANK_IS_TOO_LOW_TO_RECEIVE_THE_REWARD);
return;
}
// Check login delay.
if (activeChar.getUptime() < (Config.ATTENDANCE_REWARD_DELAY * 60 * 1000))
{
// activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_LEVEL_REQUIREMENTS_TO_RECEIVE_THE_ATTENDANCE_REWARD_PLEASE_CHECK_THE_REQUIRED_LEVEL_YOU_CAN_REDEEM_YOUR_REWARD_30_MINUTES_AFTER_LOGGING_IN);
activeChar.sendMessage("You can redeem your reward " + Config.ATTENDANCE_REWARD_DELAY + " minutes after logging in.");
return;
}
final AttendanceInfoHolder attendanceInfo = activeChar.getAttendanceInfo();
final boolean isRewardAvailable = attendanceInfo.isRewardAvailable();
final int rewardIndex = attendanceInfo.getRewardIndex();
final ItemHolder reward = AttendanceRewardData.getInstance().getRewards().get(rewardIndex);
final L2Item itemTemplate = ItemTable.getInstance().getTemplate(reward.getId());
// Weight check.
final long weight = itemTemplate.getWeight() * reward.getCount();
final long slots = itemTemplate.isStackable() ? 1 : reward.getCount();
if (!activeChar.getInventory().validateWeight(weight) || !activeChar.getInventory().validateCapacity(slots))
{
activeChar.sendPacket(SystemMessageId.THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_BECAUSE_THE_INVENTORY_WEIGHT_QUANTITY_LIMIT_HAS_BEEN_EXCEEDED);
return;
}
// Reward.
if (isRewardAvailable)
{
// Save date and index.
activeChar.setAttendanceInfo(rewardIndex + 1);
// Add items to player.
activeChar.addItem("Attendance Reward", reward, activeChar, true);
// Send message.
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_VE_RECEIVED_YOUR_VIP_ATTENDANCE_REWARD_FOR_DAY_S1);
msg.addInt(rewardIndex + 1);
activeChar.sendPacket(msg);
// Send confirm packet.
activeChar.sendPacket(new ExConfirmVipAttendanceCheck(isRewardAvailable, rewardIndex + 1));
}
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.network.clientpackets.attendance;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList;
/**
* @author Mobius
*/
public class RequestVipAttendanceItemList implements IClientIncomingPacket
{
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(L2GameClient client)
{
final L2PcInstance activeChar = client.getActiveChar();
if (activeChar == null)
{
return;
}
if (!Config.ENABLE_ATTENDANCE_REWARDS)
{
activeChar.sendPacket(SystemMessageId.DUE_TO_A_SYSTEM_ERROR_THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_PLEASE_TRY_AGAIN_LATER_BY_GOING_TO_MENU_ATTENDANCE_CHECK);
return;
}
activeChar.sendPacket(new ExVipAttendanceItemList(activeChar));
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.network.serverpackets.attendance;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.network.OutgoingPackets;
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* @author Mobius
*/
public class ExConfirmVipAttendanceCheck implements IClientOutgoingPacket
{
boolean _available;
int _index;
public ExConfirmVipAttendanceCheck(boolean rewardAvailable, int rewardIndex)
{
_available = rewardAvailable;
_index = rewardIndex;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_CONFIRM_VIP_ATTENDANCE_CHECK.writeId(packet);
packet.writeC(_available ? 0x01 : 0x00); // can receive reward today? 1 else 0
packet.writeC(_index); // active reward index
packet.writeD(0);
packet.writeD(0);
return true;
}
}

View File

@ -0,0 +1,67 @@
/*
* 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.network.serverpackets.attendance;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.network.OutgoingPackets;
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* @author Mobius
*/
public class ExVipAttendanceItemList implements IClientOutgoingPacket
{
boolean _available;
int _index;
public ExVipAttendanceItemList(L2PcInstance player)
{
final AttendanceInfoHolder attendanceInfo = player.getAttendanceInfo();
_available = attendanceInfo.isRewardAvailable();
_index = attendanceInfo.getRewardIndex();
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_VIP_ATTENDANCE_ITEM_LIST.writeId(packet);
packet.writeC(_available ? _index + 1 : _index); // index to receive?
packet.writeC(_index); // last received index?
packet.writeD(0x00);
packet.writeD(0x00);
packet.writeC(0x01);
packet.writeC(_available ? 0x01 : 0x00); // player can receive reward today?
packet.writeC(250);
packet.writeC(AttendanceRewardData.getInstance().getRewardsCount()); // reward size
int rewardCounter = 0;
for (ItemHolder reward : AttendanceRewardData.getInstance().getRewards())
{
rewardCounter++;
packet.writeD(reward.getId());
packet.writeQ(reward.getCount());
packet.writeC(0x01); // is unknown?
packet.writeC((rewardCounter % 7) == 0 ? 0x01 : 0x00); // is last in row?
}
packet.writeC(0x00);
packet.writeD(0x00);
return true;
}
}

View File

@ -67,6 +67,7 @@ Underground:
-Underground Gainak
-Automated soulshots
-Daily rewards
-Attendance rewards
Events:
-Birth of Draco

View File

@ -0,0 +1,26 @@
# ---------------------------------------------------------------------------
# Attendance Reward Settings
# ---------------------------------------------------------------------------
# Enable daily login rewards for players.
# To enable this feature you need to set L2.ini UseVIPAttendance value to true.
# Rewards are set at data\AttendanceRewards.xml file.
# Enable the Attendance Reward system.
# Default: False
EnableAttendanceRewards = False
# Enable the Attendance Reward system only for Premium accounts.
# Default: False
PremiumOnlyAttendanceRewards = False
# Make rewards sharable in the same account.
# Default: False (Each character will receive its own rewards.)
AttendanceRewardsShareAccount = False
# Time in minutes you can redeem your reward after logging in.
# Retail: 30
AttendanceRewardDelay = 30
# Popup the reward window if reward is available 30 minutes after login.
# Default: False
AttendancePopupWindow = False

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/AttendanceRewards.xsd">
<item id="23805" count="50" /> <!-- Hero Coin -->
<item id="22610" count="3" /> <!-- Luxury Cocktail -->
<item id="1540" count="10" /> <!-- Quick Healing Potion -->
<item id="22979" count="3" /> <!-- SP Rune 50% (1-hour) -->
<item id="22906" count="3" /> <!-- XP Rune III 50% (1-hour) -->
<item id="20353" count="10" /> <!-- Greater CP Potion -->
<item id="21343" count="1" /> <!-- Agathion - Cow (7-Day) -->
<item id="23805" count="100" /> <!-- Hero Coin -->
<item id="22610" count="3" /> <!-- Luxury Cocktail -->
<item id="1540" count="10" /> <!-- Quick Healing Potion -->
<item id="22979" count="3" /> <!-- SP Rune 50% (1-hour) -->
<item id="22906" count="3" /> <!-- XP Rune III 50% (1-hour) -->
<item id="20353" count="10" /> <!-- Greater CP Potion -->
<item id="21331" count="1" /> <!-- Agathion - Griffin (7-Day) -->
<item id="23805" count="150" /> <!-- Hero Coin -->
<item id="22610" count="6" /> <!-- Luxury Cocktail -->
<item id="1540" count="20" /> <!-- Quick Healing Potion -->
<item id="22979" count="5" /> <!-- SP Rune 50% (1-hour) -->
<item id="22906" count="5" /> <!-- XP Rune III 50% (1-hour) -->
<item id="20353" count="20" /> <!-- Greater CP Potion -->
<item id="21166" count="1" /> <!-- Agathion - Zaken's Spirit Swords (7-Day) -->
<item id="23805" count="300" /> <!-- Hero Coin -->
<item id="22610" count="6" /> <!-- Luxury Cocktail -->
<item id="1540" count="20" /> <!-- Quick Healing Potion -->
<item id="23284" count="5" /> <!-- SP Rune 100% (1-hour) -->
<item id="23277" count="5" /> <!-- XP Rune III 100% (1-hour) -->
<item id="23176" count="1" /> <!-- Stylish Straw Hat (30-Day) -->
<item id="22955" count="1" /> <!-- Mount - Tame Princess Ant (30-Day) -->
</list>

View File

@ -28,6 +28,7 @@ import com.l2jmobius.gameserver.data.xml.impl.AbilityPointsData;
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AppearanceItemData;
import com.l2jmobius.gameserver.data.xml.impl.ArmorSetsData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
import com.l2jmobius.gameserver.data.xml.impl.EnchantItemData;
@ -305,6 +306,12 @@ public class AdminReload implements IAdminCommandHandler
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Fishing data.");
break;
}
case "attendance":
{
AttendanceRewardData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Attendance Reward data.");
break;
}
case "fakeplayers":
{
FakePlayerData.getInstance().load();

View File

@ -0,0 +1,18 @@
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element name="item" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:int" name="id" use="required"/>
<xs:attribute type="xs:int" name="count" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -81,6 +81,7 @@ public final class Config
// --------------------------------------------------
// Config File Definitions
// --------------------------------------------------
public static final String ATTENDANCE_CONFIG_FILE = "./config/AttendanceRewards.ini";
public static final String CHARACTER_CONFIG_FILE = "./config/Character.ini";
public static final String CH_SIEGE_CONFIG_FILE = "./config/ConquerableHallSiege.ini";
public static final String FEATURE_CONFIG_FILE = "./config/Feature.ini";
@ -137,6 +138,11 @@ public final class Config
// --------------------------------------------------
// Variable Definitions
// --------------------------------------------------
public static boolean ENABLE_ATTENDANCE_REWARDS;
public static boolean PREMIUM_ONLY_ATTENDANCE_REWARDS;
public static boolean ATTENDANCE_REWARDS_SHARE_ACCOUNT;
public static int ATTENDANCE_REWARD_DELAY;
public static boolean ATTENDANCE_POPUP_WINDOW;
public static boolean PLAYER_DELEVEL;
public static int DELEVEL_MINIMUM;
public static boolean DECREASE_SKILL_LEVEL;
@ -1424,6 +1430,14 @@ public final class Config
ALLOW_WYVERN_ALWAYS = Feature.getBoolean("AllowRideWyvernAlways", false);
ALLOW_WYVERN_DURING_SIEGE = Feature.getBoolean("AllowRideWyvernDuringSiege", true);
// Load Attandance config file (if exists)
final PropertiesParser Attandance = new PropertiesParser(ATTENDANCE_CONFIG_FILE);
ENABLE_ATTENDANCE_REWARDS = Attandance.getBoolean("EnableAttendanceRewards", false);
PREMIUM_ONLY_ATTENDANCE_REWARDS = Attandance.getBoolean("PremiumOnlyAttendanceRewards", false);
ATTENDANCE_REWARDS_SHARE_ACCOUNT = Attandance.getBoolean("AttendanceRewardsShareAccount", false);
ATTENDANCE_REWARD_DELAY = Attandance.getInt("AttendanceRewardDelay", 30);
ATTENDANCE_POPUP_WINDOW = Attandance.getBoolean("AttendancePopupWindow", false);
// Load Character config file (if exists)
final PropertiesParser Character = new PropertiesParser(CHARACTER_CONFIG_FILE);

View File

@ -44,6 +44,7 @@ import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AlchemyData;
import com.l2jmobius.gameserver.data.xml.impl.AppearanceItemData;
import com.l2jmobius.gameserver.data.xml.impl.ArmorSetsData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.BeautyShopData;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.data.xml.impl.CategoryData;
@ -244,6 +245,7 @@ public class GameServer
AlchemyData.getInstance();
CommissionManager.getInstance();
LuckyGameData.getInstance();
AttendanceRewardData.getInstance();
printSection("Characters");
ClassListData.getInstance();

View File

@ -0,0 +1,100 @@
/*
* 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.data.xml.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.IGameXmlReader;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
/**
* @author Mobius
*/
public class AttendanceRewardData implements IGameXmlReader
{
private static Logger LOGGER = Logger.getLogger(AttendanceRewardData.class.getName());
private final List<ItemHolder> _rewards = new ArrayList<>();
private int _rewardsCount = 0;
protected AttendanceRewardData()
{
load();
}
@Override
public void load()
{
if (Config.ENABLE_ATTENDANCE_REWARDS)
{
getRewards().clear();
parseDatapackFile("data/AttendanceRewards.xml");
_rewardsCount = getRewards().size();
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _rewardsCount + " rewards.");
}
else
{
LOGGER.info(getClass().getSimpleName() + ": Disabled.");
}
}
@Override
public void parseDocument(Document doc, File f)
{
forEach(doc, "list", listNode -> forEach(listNode, "item", rewardNode ->
{
final StatsSet set = new StatsSet(parseAttributes(rewardNode));
final int itemId = set.getInt("id");
final int itemCount = set.getInt("count");
if (ItemTable.getInstance().getTemplate(itemId) == null)
{
LOGGER.info(getClass().getSimpleName() + ": Item with id " + itemId + " does not exist.");
}
else
{
getRewards().add(new ItemHolder(itemId, itemCount));
}
}));
}
public List<ItemHolder> getRewards()
{
return _rewards;
}
public int getRewardsCount()
{
return _rewardsCount;
}
public static AttendanceRewardData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final AttendanceRewardData _instance = new AttendanceRewardData();
}
}

View File

@ -63,6 +63,7 @@ import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
import com.l2jmobius.gameserver.data.sql.impl.CharSummonTable;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.ClassListData;
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import com.l2jmobius.gameserver.data.xml.impl.HennaData;
@ -208,6 +209,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerPvPCh
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerPvPKill;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerReputationChanged;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerSubChange;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.holders.MovieHolder;
import com.l2jmobius.gameserver.model.holders.PlayerEventHolder;
@ -847,6 +849,10 @@ public final class L2PcInstance extends L2Playable
private final static String TRAINING_CAMP_VAR = "TRAINING_CAMP";
private final static String TRAINING_CAMP_DURATION = "TRAINING_CAMP_DURATION";
// Attendance Reward system
private final static String ATTENDANCE_DATE_VAR = "ATTENDANCE_DATE";
private final static String ATTENDANCE_INDEX_VAR = "ATTENDANCE_INDEX";
// Save responder name for log it
private String _lastPetitionGmName = null;
@ -14111,4 +14117,60 @@ public final class L2PcInstance extends L2Playable
final TrainingHolder trainingHolder = getTraingCampInfo();
return (trainingHolder != null) && (trainingHolder.getEndTime() > 0);
}
public AttendanceInfoHolder getAttendanceInfo()
{
// Get reset time.
final Calendar calendar = Calendar.getInstance();
if ((calendar.get(Calendar.HOUR_OF_DAY) < 6) && (calendar.get(Calendar.MINUTE) < 30))
{
calendar.add(Calendar.DAY_OF_MONTH, -1);
}
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// Get last player reward time.
final long receiveDate;
int rewardIndex;
if (Config.ATTENDANCE_REWARDS_SHARE_ACCOUNT)
{
receiveDate = getAccountVariables().getLong(ATTENDANCE_DATE_VAR, 0);
rewardIndex = getAccountVariables().getInt(ATTENDANCE_INDEX_VAR, 0);
}
else
{
receiveDate = getVariables().getLong(ATTENDANCE_DATE_VAR, 0);
rewardIndex = getVariables().getInt(ATTENDANCE_INDEX_VAR, 0);
}
// Check if player can receive reward today.
boolean canBeRewarded = false;
if (calendar.getTimeInMillis() > receiveDate)
{
canBeRewarded = true;
// Reset index if max is reached.
if (rewardIndex >= AttendanceRewardData.getInstance().getRewardsCount())
{
rewardIndex = 0;
}
}
return new AttendanceInfoHolder(rewardIndex, canBeRewarded);
}
public void setAttendanceInfo(int rewardIndex)
{
if (Config.ATTENDANCE_REWARDS_SHARE_ACCOUNT)
{
getAccountVariables().set(ATTENDANCE_DATE_VAR, System.currentTimeMillis());
getAccountVariables().set(ATTENDANCE_INDEX_VAR, rewardIndex);
}
else
{
getVariables().set(ATTENDANCE_DATE_VAR, System.currentTimeMillis());
getVariables().set(ATTENDANCE_INDEX_VAR, rewardIndex);
}
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.holders;
/**
* @author Mobius
*/
public class AttendanceInfoHolder
{
private final int _rewardIndex;
private final boolean _rewardAvailable;
public AttendanceInfoHolder(int rewardIndex, boolean rewardAvailable)
{
_rewardIndex = rewardIndex;
_rewardAvailable = rewardAvailable;
}
public int getRewardIndex()
{
return _rewardIndex;
}
public boolean isRewardAvailable()
{
return _rewardAvailable;
}
}

View File

@ -40,6 +40,8 @@ import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExCancel
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExTryToPutShapeShiftingEnchantSupportItem;
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExTryToPutShapeShiftingTargetItem;
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestShapeShiftingItem;
import com.l2jmobius.gameserver.network.clientpackets.attendance.RequestVipAttendanceCheck;
import com.l2jmobius.gameserver.network.clientpackets.attendance.RequestVipAttendanceItemList;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.RequestChangeAttributeCancel;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.RequestChangeAttributeItem;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.SendChangeAttributeTargetItem;
@ -349,8 +351,8 @@ public enum ExIncomingPackets implements IIncomingPackets<L2GameClient>
SEND_EXECUTED_UI_EVENTS_COUNT(0x103, null, ConnectionState.IN_GAME),
EX_SEND_CLIENT_INI(0x104, null, ConnectionState.AUTHENTICATED),
REQUEST_EX_AUTO_FISH(0x105, ExRequestAutoFish::new, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_ITEM_LIST(0x106, null, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_CHECK(0x107, null, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_ITEM_LIST(0x106, RequestVipAttendanceItemList::new, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_CHECK(0x107, RequestVipAttendanceCheck::new, ConnectionState.IN_GAME),
REQUEST_ITEM_ENSOUL(0x108, RequestItemEnsoul::new, ConnectionState.IN_GAME),
REQUEST_CASTLE_WAR_SEASON_REWARD(0x109, null, ConnectionState.IN_GAME),
REQUEST_VIP_PRODUCT_LIST(0x10A, null, ConnectionState.IN_GAME),

View File

@ -51,6 +51,7 @@ import com.l2jmobius.gameserver.model.entity.Fort;
import com.l2jmobius.gameserver.model.entity.FortSiege;
import com.l2jmobius.gameserver.model.entity.L2Event;
import com.l2jmobius.gameserver.model.entity.Siege;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.instancezone.Instance;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.quest.Quest;
@ -98,6 +99,7 @@ import com.l2jmobius.gameserver.network.serverpackets.SkillCoolTime;
import com.l2jmobius.gameserver.network.serverpackets.SkillList;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.ability.ExAcquireAPSkillList;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList;
import com.l2jmobius.gameserver.network.serverpackets.dailymission.ExOneDayReceiveRewardList;
import com.l2jmobius.gameserver.network.serverpackets.friend.L2FriendList;
@ -653,6 +655,26 @@ public class EnterWorld implements IClientIncomingPacket
activeChar.updateAbnormalVisualEffects();
}
if (Config.ENABLE_ATTENDANCE_REWARDS)
{
ThreadPoolManager.schedule(() ->
{
// Check if player can receive reward today.
final AttendanceInfoHolder attendanceInfo = activeChar.getAttendanceInfo();
if (attendanceInfo.isRewardAvailable())
{
final int lastRewardIndex = attendanceInfo.getRewardIndex() + 1;
activeChar.sendPacket(new ExShowScreenMessage("Your attendance day " + lastRewardIndex + " reward is ready.", ExShowScreenMessage.TOP_CENTER, 7000, 0, true, true));
activeChar.sendMessage("Your attendance day " + lastRewardIndex + " reward is ready.");
activeChar.sendMessage("Click on General Menu -> Attendance Check.");
if (Config.ATTENDANCE_POPUP_WINDOW)
{
activeChar.sendPacket(new ExVipAttendanceItemList(activeChar));
}
}
}, Config.ATTENDANCE_REWARD_DELAY * 60 * 1000);
}
if (Config.HARDWARE_INFO_ENABLED)
{
ThreadPoolManager.schedule(() ->

View File

@ -0,0 +1,103 @@
/*
* 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.network.clientpackets.attendance;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExConfirmVipAttendanceCheck;
/**
* @author Mobius
*/
public class RequestVipAttendanceCheck implements IClientIncomingPacket
{
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(L2GameClient client)
{
final L2PcInstance activeChar = client.getActiveChar();
if (activeChar == null)
{
return;
}
if (!Config.ENABLE_ATTENDANCE_REWARDS)
{
activeChar.sendPacket(SystemMessageId.DUE_TO_A_SYSTEM_ERROR_THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_PLEASE_TRY_AGAIN_LATER_BY_GOING_TO_MENU_ATTENDANCE_CHECK);
return;
}
if (Config.PREMIUM_ONLY_ATTENDANCE_REWARDS && !activeChar.hasPremiumStatus())
{
activeChar.sendPacket(SystemMessageId.YOUR_VIP_RANK_IS_TOO_LOW_TO_RECEIVE_THE_REWARD);
return;
}
// Check login delay.
if (activeChar.getUptime() < (Config.ATTENDANCE_REWARD_DELAY * 60 * 1000))
{
// activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_LEVEL_REQUIREMENTS_TO_RECEIVE_THE_ATTENDANCE_REWARD_PLEASE_CHECK_THE_REQUIRED_LEVEL_YOU_CAN_REDEEM_YOUR_REWARD_30_MINUTES_AFTER_LOGGING_IN);
activeChar.sendMessage("You can redeem your reward " + Config.ATTENDANCE_REWARD_DELAY + " minutes after logging in.");
return;
}
final AttendanceInfoHolder attendanceInfo = activeChar.getAttendanceInfo();
final boolean isRewardAvailable = attendanceInfo.isRewardAvailable();
final int rewardIndex = attendanceInfo.getRewardIndex();
final ItemHolder reward = AttendanceRewardData.getInstance().getRewards().get(rewardIndex);
final L2Item itemTemplate = ItemTable.getInstance().getTemplate(reward.getId());
// Weight check.
final long weight = itemTemplate.getWeight() * reward.getCount();
final long slots = itemTemplate.isStackable() ? 1 : reward.getCount();
if (!activeChar.getInventory().validateWeight(weight) || !activeChar.getInventory().validateCapacity(slots))
{
activeChar.sendPacket(SystemMessageId.THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_BECAUSE_THE_INVENTORY_WEIGHT_QUANTITY_LIMIT_HAS_BEEN_EXCEEDED);
return;
}
// Reward.
if (isRewardAvailable)
{
// Save date and index.
activeChar.setAttendanceInfo(rewardIndex + 1);
// Add items to player.
activeChar.addItem("Attendance Reward", reward, activeChar, true);
// Send message.
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_VE_RECEIVED_YOUR_VIP_ATTENDANCE_REWARD_FOR_DAY_S1);
msg.addInt(rewardIndex + 1);
activeChar.sendPacket(msg);
// Send confirm packet.
activeChar.sendPacket(new ExConfirmVipAttendanceCheck(isRewardAvailable, rewardIndex + 1));
}
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.network.clientpackets.attendance;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList;
/**
* @author Mobius
*/
public class RequestVipAttendanceItemList implements IClientIncomingPacket
{
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(L2GameClient client)
{
final L2PcInstance activeChar = client.getActiveChar();
if (activeChar == null)
{
return;
}
if (!Config.ENABLE_ATTENDANCE_REWARDS)
{
activeChar.sendPacket(SystemMessageId.DUE_TO_A_SYSTEM_ERROR_THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_PLEASE_TRY_AGAIN_LATER_BY_GOING_TO_MENU_ATTENDANCE_CHECK);
return;
}
activeChar.sendPacket(new ExVipAttendanceItemList(activeChar));
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.network.serverpackets.attendance;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.network.OutgoingPackets;
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* @author Mobius
*/
public class ExConfirmVipAttendanceCheck implements IClientOutgoingPacket
{
boolean _available;
int _index;
public ExConfirmVipAttendanceCheck(boolean rewardAvailable, int rewardIndex)
{
_available = rewardAvailable;
_index = rewardIndex;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_CONFIRM_VIP_ATTENDANCE_CHECK.writeId(packet);
packet.writeC(_available ? 0x01 : 0x00); // can receive reward today? 1 else 0
packet.writeC(_index); // active reward index
packet.writeD(0);
packet.writeD(0);
return true;
}
}

View File

@ -0,0 +1,67 @@
/*
* 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.network.serverpackets.attendance;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.network.OutgoingPackets;
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* @author Mobius
*/
public class ExVipAttendanceItemList implements IClientOutgoingPacket
{
boolean _available;
int _index;
public ExVipAttendanceItemList(L2PcInstance player)
{
final AttendanceInfoHolder attendanceInfo = player.getAttendanceInfo();
_available = attendanceInfo.isRewardAvailable();
_index = attendanceInfo.getRewardIndex();
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_VIP_ATTENDANCE_ITEM_LIST.writeId(packet);
packet.writeC(_available ? _index + 1 : _index); // index to receive?
packet.writeC(_index); // last received index?
packet.writeD(0x00);
packet.writeD(0x00);
packet.writeC(0x01);
packet.writeC(_available ? 0x01 : 0x00); // player can receive reward today?
packet.writeC(250);
packet.writeC(AttendanceRewardData.getInstance().getRewardsCount()); // reward size
int rewardCounter = 0;
for (ItemHolder reward : AttendanceRewardData.getInstance().getRewards())
{
rewardCounter++;
packet.writeD(reward.getId());
packet.writeQ(reward.getCount());
packet.writeC(0x01); // is unknown?
packet.writeC((rewardCounter % 7) == 0 ? 0x01 : 0x00); // is last in row?
}
packet.writeC(0x00);
packet.writeD(0x00);
return true;
}
}

View File

@ -67,6 +67,7 @@ Underground:
-Underground Gainak
-Automated soulshots
-Daily rewards
-Attendance rewards
Helios:
-Dimensional Rift

View File

@ -0,0 +1,26 @@
# ---------------------------------------------------------------------------
# Attendance Reward Settings
# ---------------------------------------------------------------------------
# Enable daily login rewards for players.
# To enable this feature you need to set L2.ini UseVIPAttendance value to true.
# Rewards are set at data\AttendanceRewards.xml file.
# Enable the Attendance Reward system.
# Default: False
EnableAttendanceRewards = False
# Enable the Attendance Reward system only for Premium accounts.
# Default: False
PremiumOnlyAttendanceRewards = False
# Make rewards sharable in the same account.
# Default: False (Each character will receive its own rewards.)
AttendanceRewardsShareAccount = False
# Time in minutes you can redeem your reward after logging in.
# Retail: 30
AttendanceRewardDelay = 30
# Popup the reward window if reward is available 30 minutes after login.
# Default: False
AttendancePopupWindow = False

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/AttendanceRewards.xsd">
<item id="23805" count="50" /> <!-- Hero Coin -->
<item id="22610" count="3" /> <!-- Luxury Cocktail -->
<item id="1540" count="10" /> <!-- Quick Healing Potion -->
<item id="22979" count="3" /> <!-- SP Rune 50% (1-hour) -->
<item id="22906" count="3" /> <!-- XP Rune III 50% (1-hour) -->
<item id="20353" count="10" /> <!-- Greater CP Potion -->
<item id="21343" count="1" /> <!-- Agathion - Cow (7-Day) -->
<item id="23805" count="100" /> <!-- Hero Coin -->
<item id="22610" count="3" /> <!-- Luxury Cocktail -->
<item id="1540" count="10" /> <!-- Quick Healing Potion -->
<item id="22979" count="3" /> <!-- SP Rune 50% (1-hour) -->
<item id="22906" count="3" /> <!-- XP Rune III 50% (1-hour) -->
<item id="20353" count="10" /> <!-- Greater CP Potion -->
<item id="21331" count="1" /> <!-- Agathion - Griffin (7-Day) -->
<item id="23805" count="150" /> <!-- Hero Coin -->
<item id="22610" count="6" /> <!-- Luxury Cocktail -->
<item id="1540" count="20" /> <!-- Quick Healing Potion -->
<item id="22979" count="5" /> <!-- SP Rune 50% (1-hour) -->
<item id="22906" count="5" /> <!-- XP Rune III 50% (1-hour) -->
<item id="20353" count="20" /> <!-- Greater CP Potion -->
<item id="21166" count="1" /> <!-- Agathion - Zaken's Spirit Swords (7-Day) -->
<item id="23805" count="300" /> <!-- Hero Coin -->
<item id="22610" count="6" /> <!-- Luxury Cocktail -->
<item id="1540" count="20" /> <!-- Quick Healing Potion -->
<item id="23284" count="5" /> <!-- SP Rune 100% (1-hour) -->
<item id="23277" count="5" /> <!-- XP Rune III 100% (1-hour) -->
<item id="23176" count="1" /> <!-- Stylish Straw Hat (30-Day) -->
<item id="22955" count="1" /> <!-- Mount - Tame Princess Ant (30-Day) -->
</list>

View File

@ -27,6 +27,7 @@ import com.l2jmobius.gameserver.data.sql.impl.CrestTable;
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AppearanceItemData;
import com.l2jmobius.gameserver.data.xml.impl.ArmorSetsData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
import com.l2jmobius.gameserver.data.xml.impl.EnchantItemData;
@ -298,6 +299,12 @@ public class AdminReload implements IAdminCommandHandler
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Fishing data.");
break;
}
case "attendance":
{
AttendanceRewardData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Attendance Reward data.");
break;
}
case "fakeplayers":
{
FakePlayerData.getInstance().load();

View File

@ -0,0 +1,18 @@
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element name="item" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:int" name="id" use="required"/>
<xs:attribute type="xs:int" name="count" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -81,6 +81,7 @@ public final class Config
// --------------------------------------------------
// Config File Definitions
// --------------------------------------------------
public static final String ATTENDANCE_CONFIG_FILE = "./config/AttendanceRewards.ini";
public static final String CHARACTER_CONFIG_FILE = "./config/Character.ini";
public static final String CH_SIEGE_CONFIG_FILE = "./config/ConquerableHallSiege.ini";
public static final String FEATURE_CONFIG_FILE = "./config/Feature.ini";
@ -137,6 +138,11 @@ public final class Config
// --------------------------------------------------
// Variable Definitions
// --------------------------------------------------
public static boolean ENABLE_ATTENDANCE_REWARDS;
public static boolean PREMIUM_ONLY_ATTENDANCE_REWARDS;
public static boolean ATTENDANCE_REWARDS_SHARE_ACCOUNT;
public static int ATTENDANCE_REWARD_DELAY;
public static boolean ATTENDANCE_POPUP_WINDOW;
public static boolean PLAYER_DELEVEL;
public static int DELEVEL_MINIMUM;
public static boolean DECREASE_SKILL_LEVEL;
@ -1423,6 +1429,14 @@ public final class Config
ALLOW_WYVERN_ALWAYS = Feature.getBoolean("AllowRideWyvernAlways", false);
ALLOW_WYVERN_DURING_SIEGE = Feature.getBoolean("AllowRideWyvernDuringSiege", true);
// Load Attandance config file (if exists)
final PropertiesParser Attandance = new PropertiesParser(ATTENDANCE_CONFIG_FILE);
ENABLE_ATTENDANCE_REWARDS = Attandance.getBoolean("EnableAttendanceRewards", false);
PREMIUM_ONLY_ATTENDANCE_REWARDS = Attandance.getBoolean("PremiumOnlyAttendanceRewards", false);
ATTENDANCE_REWARDS_SHARE_ACCOUNT = Attandance.getBoolean("AttendanceRewardsShareAccount", false);
ATTENDANCE_REWARD_DELAY = Attandance.getInt("AttendanceRewardDelay", 30);
ATTENDANCE_POPUP_WINDOW = Attandance.getBoolean("AttendancePopupWindow", false);
// Load Character config file (if exists)
final PropertiesParser Character = new PropertiesParser(CHARACTER_CONFIG_FILE);

View File

@ -43,6 +43,7 @@ import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AlchemyData;
import com.l2jmobius.gameserver.data.xml.impl.AppearanceItemData;
import com.l2jmobius.gameserver.data.xml.impl.ArmorSetsData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.BeautyShopData;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.data.xml.impl.CategoryData;
@ -243,6 +244,7 @@ public class GameServer
AlchemyData.getInstance();
CommissionManager.getInstance();
LuckyGameData.getInstance();
AttendanceRewardData.getInstance();
printSection("Characters");
ClassListData.getInstance();

View File

@ -0,0 +1,100 @@
/*
* 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.data.xml.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.IGameXmlReader;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
/**
* @author Mobius
*/
public class AttendanceRewardData implements IGameXmlReader
{
private static Logger LOGGER = Logger.getLogger(AttendanceRewardData.class.getName());
private final List<ItemHolder> _rewards = new ArrayList<>();
private int _rewardsCount = 0;
protected AttendanceRewardData()
{
load();
}
@Override
public void load()
{
if (Config.ENABLE_ATTENDANCE_REWARDS)
{
getRewards().clear();
parseDatapackFile("data/AttendanceRewards.xml");
_rewardsCount = getRewards().size();
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _rewardsCount + " rewards.");
}
else
{
LOGGER.info(getClass().getSimpleName() + ": Disabled.");
}
}
@Override
public void parseDocument(Document doc, File f)
{
forEach(doc, "list", listNode -> forEach(listNode, "item", rewardNode ->
{
final StatsSet set = new StatsSet(parseAttributes(rewardNode));
final int itemId = set.getInt("id");
final int itemCount = set.getInt("count");
if (ItemTable.getInstance().getTemplate(itemId) == null)
{
LOGGER.info(getClass().getSimpleName() + ": Item with id " + itemId + " does not exist.");
}
else
{
getRewards().add(new ItemHolder(itemId, itemCount));
}
}));
}
public List<ItemHolder> getRewards()
{
return _rewards;
}
public int getRewardsCount()
{
return _rewardsCount;
}
public static AttendanceRewardData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final AttendanceRewardData _instance = new AttendanceRewardData();
}
}

View File

@ -62,6 +62,7 @@ import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
import com.l2jmobius.gameserver.data.sql.impl.CharSummonTable;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.CategoryData;
import com.l2jmobius.gameserver.data.xml.impl.ClassListData;
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
@ -207,6 +208,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerPvPCh
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerPvPKill;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerReputationChanged;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerSubChange;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.holders.MonsterBookCardHolder;
import com.l2jmobius.gameserver.model.holders.MonsterBookRewardHolder;
@ -850,13 +852,17 @@ public final class L2PcInstance extends L2Playable
_PvPRegTask = null;
}
// Monster Book variables
private final static String MONSTER_BOOK_KILLS_VAR = "MONSTER_BOOK_KILLS_";
private final static String MONSTER_BOOK_LEVEL_VAR = "MONSTER_BOOK_LEVEL_";
// Training Camp
private final static String TRAINING_CAMP_VAR = "TRAINING_CAMP";
private final static String TRAINING_CAMP_DURATION = "TRAINING_CAMP_DURATION";
// Monster Book variables
private final static String MONSTER_BOOK_KILLS_VAR = "MONSTER_BOOK_KILLS_";
private final static String MONSTER_BOOK_LEVEL_VAR = "MONSTER_BOOK_LEVEL_";
// Attendance Reward system
private final static String ATTENDANCE_DATE_VAR = "ATTENDANCE_DATE";
private final static String ATTENDANCE_INDEX_VAR = "ATTENDANCE_INDEX";
// Save responder name for log it
private String _lastPetitionGmName = null;
@ -14124,4 +14130,60 @@ public final class L2PcInstance extends L2Playable
final TrainingHolder trainingHolder = getTraingCampInfo();
return (trainingHolder != null) && (trainingHolder.getEndTime() > 0);
}
public AttendanceInfoHolder getAttendanceInfo()
{
// Get reset time.
final Calendar calendar = Calendar.getInstance();
if ((calendar.get(Calendar.HOUR_OF_DAY) < 6) && (calendar.get(Calendar.MINUTE) < 30))
{
calendar.add(Calendar.DAY_OF_MONTH, -1);
}
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// Get last player reward time.
final long receiveDate;
int rewardIndex;
if (Config.ATTENDANCE_REWARDS_SHARE_ACCOUNT)
{
receiveDate = getAccountVariables().getLong(ATTENDANCE_DATE_VAR, 0);
rewardIndex = getAccountVariables().getInt(ATTENDANCE_INDEX_VAR, 0);
}
else
{
receiveDate = getVariables().getLong(ATTENDANCE_DATE_VAR, 0);
rewardIndex = getVariables().getInt(ATTENDANCE_INDEX_VAR, 0);
}
// Check if player can receive reward today.
boolean canBeRewarded = false;
if (calendar.getTimeInMillis() > receiveDate)
{
canBeRewarded = true;
// Reset index if max is reached.
if (rewardIndex >= AttendanceRewardData.getInstance().getRewardsCount())
{
rewardIndex = 0;
}
}
return new AttendanceInfoHolder(rewardIndex, canBeRewarded);
}
public void setAttendanceInfo(int rewardIndex)
{
if (Config.ATTENDANCE_REWARDS_SHARE_ACCOUNT)
{
getAccountVariables().set(ATTENDANCE_DATE_VAR, System.currentTimeMillis());
getAccountVariables().set(ATTENDANCE_INDEX_VAR, rewardIndex);
}
else
{
getVariables().set(ATTENDANCE_DATE_VAR, System.currentTimeMillis());
getVariables().set(ATTENDANCE_INDEX_VAR, rewardIndex);
}
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.holders;
/**
* @author Mobius
*/
public class AttendanceInfoHolder
{
private final int _rewardIndex;
private final boolean _rewardAvailable;
public AttendanceInfoHolder(int rewardIndex, boolean rewardAvailable)
{
_rewardIndex = rewardIndex;
_rewardAvailable = rewardAvailable;
}
public int getRewardIndex()
{
return _rewardIndex;
}
public boolean isRewardAvailable()
{
return _rewardAvailable;
}
}

View File

@ -40,6 +40,8 @@ import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExCancel
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExTryToPutShapeShiftingEnchantSupportItem;
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExTryToPutShapeShiftingTargetItem;
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestShapeShiftingItem;
import com.l2jmobius.gameserver.network.clientpackets.attendance.RequestVipAttendanceCheck;
import com.l2jmobius.gameserver.network.clientpackets.attendance.RequestVipAttendanceItemList;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.RequestChangeAttributeCancel;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.RequestChangeAttributeItem;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.SendChangeAttributeTargetItem;
@ -356,8 +358,8 @@ public enum ExIncomingPackets implements IIncomingPackets<L2GameClient>
SEND_EXECUTED_UI_EVENTS_COUNT(0x103, null, ConnectionState.IN_GAME),
EX_SEND_CLIENT_INI(0x104, null, ConnectionState.AUTHENTICATED),
REQUEST_EX_AUTO_FISH(0x105, ExRequestAutoFish::new, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_ITEM_LIST(0x106, null, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_CHECK(0x107, null, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_ITEM_LIST(0x106, RequestVipAttendanceItemList::new, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_CHECK(0x107, RequestVipAttendanceCheck::new, ConnectionState.IN_GAME),
REQUEST_ITEM_ENSOUL(0x108, RequestItemEnsoul::new, ConnectionState.IN_GAME),
REQUEST_CASTLE_WAR_SEASON_REWARD(0x109, null, ConnectionState.IN_GAME),
REQUEST_VIP_PRODUCT_LIST(0x10A, null, ConnectionState.IN_GAME),

View File

@ -51,6 +51,7 @@ import com.l2jmobius.gameserver.model.entity.Fort;
import com.l2jmobius.gameserver.model.entity.FortSiege;
import com.l2jmobius.gameserver.model.entity.L2Event;
import com.l2jmobius.gameserver.model.entity.Siege;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.instancezone.Instance;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.quest.Quest;
@ -98,6 +99,7 @@ import com.l2jmobius.gameserver.network.serverpackets.SkillCoolTime;
import com.l2jmobius.gameserver.network.serverpackets.SkillList;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.ability.ExAcquireAPSkillList;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList;
import com.l2jmobius.gameserver.network.serverpackets.dailymission.ExOneDayReceiveRewardList;
import com.l2jmobius.gameserver.network.serverpackets.friend.L2FriendList;
@ -653,6 +655,26 @@ public class EnterWorld implements IClientIncomingPacket
activeChar.updateAbnormalVisualEffects();
}
if (Config.ENABLE_ATTENDANCE_REWARDS)
{
ThreadPoolManager.schedule(() ->
{
// Check if player can receive reward today.
final AttendanceInfoHolder attendanceInfo = activeChar.getAttendanceInfo();
if (attendanceInfo.isRewardAvailable())
{
final int lastRewardIndex = attendanceInfo.getRewardIndex() + 1;
activeChar.sendPacket(new ExShowScreenMessage("Your attendance day " + lastRewardIndex + " reward is ready.", ExShowScreenMessage.TOP_CENTER, 7000, 0, true, true));
activeChar.sendMessage("Your attendance day " + lastRewardIndex + " reward is ready.");
activeChar.sendMessage("Click on General Menu -> Attendance Check.");
if (Config.ATTENDANCE_POPUP_WINDOW)
{
activeChar.sendPacket(new ExVipAttendanceItemList(activeChar));
}
}
}, Config.ATTENDANCE_REWARD_DELAY * 60 * 1000);
}
if (Config.HARDWARE_INFO_ENABLED)
{
ThreadPoolManager.schedule(() ->

View File

@ -0,0 +1,103 @@
/*
* 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.network.clientpackets.attendance;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExConfirmVipAttendanceCheck;
/**
* @author Mobius
*/
public class RequestVipAttendanceCheck implements IClientIncomingPacket
{
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(L2GameClient client)
{
final L2PcInstance activeChar = client.getActiveChar();
if (activeChar == null)
{
return;
}
if (!Config.ENABLE_ATTENDANCE_REWARDS)
{
activeChar.sendPacket(SystemMessageId.DUE_TO_A_SYSTEM_ERROR_THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_PLEASE_TRY_AGAIN_LATER_BY_GOING_TO_MENU_ATTENDANCE_CHECK);
return;
}
if (Config.PREMIUM_ONLY_ATTENDANCE_REWARDS && !activeChar.hasPremiumStatus())
{
activeChar.sendPacket(SystemMessageId.YOUR_VIP_RANK_IS_TOO_LOW_TO_RECEIVE_THE_REWARD);
return;
}
// Check login delay.
if (activeChar.getUptime() < (Config.ATTENDANCE_REWARD_DELAY * 60 * 1000))
{
// activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_LEVEL_REQUIREMENTS_TO_RECEIVE_THE_ATTENDANCE_REWARD_PLEASE_CHECK_THE_REQUIRED_LEVEL_YOU_CAN_REDEEM_YOUR_REWARD_30_MINUTES_AFTER_LOGGING_IN);
activeChar.sendMessage("You can redeem your reward " + Config.ATTENDANCE_REWARD_DELAY + " minutes after logging in.");
return;
}
final AttendanceInfoHolder attendanceInfo = activeChar.getAttendanceInfo();
final boolean isRewardAvailable = attendanceInfo.isRewardAvailable();
final int rewardIndex = attendanceInfo.getRewardIndex();
final ItemHolder reward = AttendanceRewardData.getInstance().getRewards().get(rewardIndex);
final L2Item itemTemplate = ItemTable.getInstance().getTemplate(reward.getId());
// Weight check.
final long weight = itemTemplate.getWeight() * reward.getCount();
final long slots = itemTemplate.isStackable() ? 1 : reward.getCount();
if (!activeChar.getInventory().validateWeight(weight) || !activeChar.getInventory().validateCapacity(slots))
{
activeChar.sendPacket(SystemMessageId.THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_BECAUSE_THE_INVENTORY_WEIGHT_QUANTITY_LIMIT_HAS_BEEN_EXCEEDED);
return;
}
// Reward.
if (isRewardAvailable)
{
// Save date and index.
activeChar.setAttendanceInfo(rewardIndex + 1);
// Add items to player.
activeChar.addItem("Attendance Reward", reward, activeChar, true);
// Send message.
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_VE_RECEIVED_YOUR_VIP_ATTENDANCE_REWARD_FOR_DAY_S1);
msg.addInt(rewardIndex + 1);
activeChar.sendPacket(msg);
// Send confirm packet.
activeChar.sendPacket(new ExConfirmVipAttendanceCheck(isRewardAvailable, rewardIndex + 1));
}
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.network.clientpackets.attendance;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList;
/**
* @author Mobius
*/
public class RequestVipAttendanceItemList implements IClientIncomingPacket
{
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(L2GameClient client)
{
final L2PcInstance activeChar = client.getActiveChar();
if (activeChar == null)
{
return;
}
if (!Config.ENABLE_ATTENDANCE_REWARDS)
{
activeChar.sendPacket(SystemMessageId.DUE_TO_A_SYSTEM_ERROR_THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_PLEASE_TRY_AGAIN_LATER_BY_GOING_TO_MENU_ATTENDANCE_CHECK);
return;
}
activeChar.sendPacket(new ExVipAttendanceItemList(activeChar));
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.network.serverpackets.attendance;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.network.OutgoingPackets;
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* @author Mobius
*/
public class ExConfirmVipAttendanceCheck implements IClientOutgoingPacket
{
boolean _available;
int _index;
public ExConfirmVipAttendanceCheck(boolean rewardAvailable, int rewardIndex)
{
_available = rewardAvailable;
_index = rewardIndex;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_CONFIRM_VIP_ATTENDANCE_CHECK.writeId(packet);
packet.writeC(_available ? 0x01 : 0x00); // can receive reward today? 1 else 0
packet.writeC(_index); // active reward index
packet.writeD(0);
packet.writeD(0);
return true;
}
}

View File

@ -0,0 +1,67 @@
/*
* 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.network.serverpackets.attendance;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.network.OutgoingPackets;
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* @author Mobius
*/
public class ExVipAttendanceItemList implements IClientOutgoingPacket
{
boolean _available;
int _index;
public ExVipAttendanceItemList(L2PcInstance player)
{
final AttendanceInfoHolder attendanceInfo = player.getAttendanceInfo();
_available = attendanceInfo.isRewardAvailable();
_index = attendanceInfo.getRewardIndex();
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_VIP_ATTENDANCE_ITEM_LIST.writeId(packet);
packet.writeC(_available ? _index + 1 : _index); // index to receive?
packet.writeC(_index); // last received index?
packet.writeD(0x00);
packet.writeD(0x00);
packet.writeC(0x01);
packet.writeC(_available ? 0x01 : 0x00); // player can receive reward today?
packet.writeC(250);
packet.writeC(AttendanceRewardData.getInstance().getRewardsCount()); // reward size
int rewardCounter = 0;
for (ItemHolder reward : AttendanceRewardData.getInstance().getRewards())
{
rewardCounter++;
packet.writeD(reward.getId());
packet.writeQ(reward.getCount());
packet.writeC(0x01); // is unknown?
packet.writeC((rewardCounter % 7) == 0 ? 0x01 : 0x00); // is last in row?
}
packet.writeC(0x00);
packet.writeD(0x00);
return true;
}
}

View File

@ -67,6 +67,7 @@ Underground:
-Underground Gainak
-Automated soulshots
-Daily rewards
-Attendance rewards
Helios:
-Dimensional Rift

View File

@ -0,0 +1,26 @@
# ---------------------------------------------------------------------------
# Attendance Reward Settings
# ---------------------------------------------------------------------------
# Enable daily login rewards for players.
# To enable this feature you need to set L2.ini UseVIPAttendance value to true.
# Rewards are set at data\AttendanceRewards.xml file.
# Enable the Attendance Reward system.
# Default: False
EnableAttendanceRewards = False
# Enable the Attendance Reward system only for Premium accounts.
# Default: False
PremiumOnlyAttendanceRewards = False
# Make rewards sharable in the same account.
# Default: False (Each character will receive its own rewards.)
AttendanceRewardsShareAccount = False
# Time in minutes you can redeem your reward after logging in.
# Retail: 30
AttendanceRewardDelay = 30
# Popup the reward window if reward is available 30 minutes after login.
# Default: False
AttendancePopupWindow = False

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/AttendanceRewards.xsd">
<item id="29564" count="50" /> <!-- Attendance Coin -->
<item id="29553" count="3" /> <!-- 2nd Class Buff Scroll -->
<item id="29554" count="10" /> <!-- Quick Healing Potion -->
<item id="29565" count="3" /> <!-- XP/SP Scroll -->
<item id="29584" count="2" /> <!-- Angel Cat's Blessing Chest -->
<item id="29566" count="1" /> <!-- Attendance XP Rune -->
<item id="29585" count="1" /> <!-- Refined Romantic Chapeau -->
<item id="29564" count="100" /> <!-- Attendance Coin -->
<item id="29553" count="3" /> <!-- 2nd Class Buff Scroll -->
<item id="29554" count="10" /> <!-- Quick Healing Potion -->
<item id="29519" count="3" /> <!-- XP/SP Scroll - Medium -->
<item id="29584" count="2" /> <!-- Angel Cat's Blessing Chest -->
<item id="29566" count="1" /> <!-- Attendance XP Rune -->
<item id="49512" count="1" /> <!-- Amulet: Prosperity -->
<item id="29564" count="150" /> <!-- Attendance Coin -->
<item id="29553" count="6" /> <!-- 2nd Class Buff Scroll -->
<item id="29554" count="10" /> <!-- Quick Healing Potion -->
<item id="29519" count="3" /> <!-- XP/SP Scroll - Medium -->
<item id="29584" count="4" /> <!-- Angel Cat's Blessing Chest -->
<item id="29566" count="1" /> <!-- Attendance XP Rune -->
<item id="29578" count="1" /> <!-- Rare Accessory Pack -->
<item id="29564" count="300" /> <!-- Attendance Coin -->
<item id="29553" count="6" /> <!-- 2nd Class Buff Scroll -->
<item id="29554" count="10" /> <!-- Quick Healing Potion -->
<item id="29650" count="5" /> <!-- XP/SP Scroll - High -->
<item id="29584" count="4" /> <!-- Angel Cat's Blessing Chest -->
<item id="29566" count="1" /> <!-- Attendance XP Rune -->
<item id="29587" count="1" /> <!-- Agathion - Singer & Dancer -->
</list>

View File

@ -28,6 +28,7 @@ import com.l2jmobius.gameserver.data.xml.impl.AbilityPointsData;
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AppearanceItemData;
import com.l2jmobius.gameserver.data.xml.impl.ArmorSetsData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
import com.l2jmobius.gameserver.data.xml.impl.EnchantItemData;
@ -305,6 +306,12 @@ public class AdminReload implements IAdminCommandHandler
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Fishing data.");
break;
}
case "attendance":
{
AttendanceRewardData.getInstance().load();
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Attendance Reward data.");
break;
}
case "fakeplayers":
{
FakePlayerData.getInstance().load();

View File

@ -0,0 +1,18 @@
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element name="item" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:int" name="id" use="required"/>
<xs:attribute type="xs:int" name="count" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -81,6 +81,7 @@ public final class Config
// --------------------------------------------------
// Config File Definitions
// --------------------------------------------------
public static final String ATTENDANCE_CONFIG_FILE = "./config/AttendanceRewards.ini";
public static final String CHARACTER_CONFIG_FILE = "./config/Character.ini";
public static final String CH_SIEGE_CONFIG_FILE = "./config/ConquerableHallSiege.ini";
public static final String FEATURE_CONFIG_FILE = "./config/Feature.ini";
@ -137,6 +138,11 @@ public final class Config
// --------------------------------------------------
// Variable Definitions
// --------------------------------------------------
public static boolean ENABLE_ATTENDANCE_REWARDS;
public static boolean PREMIUM_ONLY_ATTENDANCE_REWARDS;
public static boolean ATTENDANCE_REWARDS_SHARE_ACCOUNT;
public static int ATTENDANCE_REWARD_DELAY;
public static boolean ATTENDANCE_POPUP_WINDOW;
public static boolean PLAYER_DELEVEL;
public static int DELEVEL_MINIMUM;
public static boolean DECREASE_SKILL_LEVEL;
@ -1354,6 +1360,14 @@ public final class Config
ALLOW_WYVERN_ALWAYS = Feature.getBoolean("AllowRideWyvernAlways", false);
ALLOW_WYVERN_DURING_SIEGE = Feature.getBoolean("AllowRideWyvernDuringSiege", true);
// Load Attandance config file (if exists)
final PropertiesParser Attandance = new PropertiesParser(ATTENDANCE_CONFIG_FILE);
ENABLE_ATTENDANCE_REWARDS = Attandance.getBoolean("EnableAttendanceRewards", false);
PREMIUM_ONLY_ATTENDANCE_REWARDS = Attandance.getBoolean("PremiumOnlyAttendanceRewards", false);
ATTENDANCE_REWARDS_SHARE_ACCOUNT = Attandance.getBoolean("AttendanceRewardsShareAccount", false);
ATTENDANCE_REWARD_DELAY = Attandance.getInt("AttendanceRewardDelay", 30);
ATTENDANCE_POPUP_WINDOW = Attandance.getBoolean("AttendancePopupWindow", false);
// Load Character config file (if exists)
final PropertiesParser Character = new PropertiesParser(CHARACTER_CONFIG_FILE);

View File

@ -44,6 +44,7 @@ import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AlchemyData;
import com.l2jmobius.gameserver.data.xml.impl.AppearanceItemData;
import com.l2jmobius.gameserver.data.xml.impl.ArmorSetsData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.BeautyShopData;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.data.xml.impl.CategoryData;
@ -242,6 +243,7 @@ public class GameServer
AlchemyData.getInstance();
CommissionManager.getInstance();
LuckyGameData.getInstance();
AttendanceRewardData.getInstance();
printSection("Characters");
ClassListData.getInstance();

View File

@ -0,0 +1,100 @@
/*
* 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.data.xml.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.IGameXmlReader;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
/**
* @author Mobius
*/
public class AttendanceRewardData implements IGameXmlReader
{
private static Logger LOGGER = Logger.getLogger(AttendanceRewardData.class.getName());
private final List<ItemHolder> _rewards = new ArrayList<>();
private int _rewardsCount = 0;
protected AttendanceRewardData()
{
load();
}
@Override
public void load()
{
if (Config.ENABLE_ATTENDANCE_REWARDS)
{
getRewards().clear();
parseDatapackFile("data/AttendanceRewards.xml");
_rewardsCount = getRewards().size();
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _rewardsCount + " rewards.");
}
else
{
LOGGER.info(getClass().getSimpleName() + ": Disabled.");
}
}
@Override
public void parseDocument(Document doc, File f)
{
forEach(doc, "list", listNode -> forEach(listNode, "item", rewardNode ->
{
final StatsSet set = new StatsSet(parseAttributes(rewardNode));
final int itemId = set.getInt("id");
final int itemCount = set.getInt("count");
if (ItemTable.getInstance().getTemplate(itemId) == null)
{
LOGGER.info(getClass().getSimpleName() + ": Item with id " + itemId + " does not exist.");
}
else
{
getRewards().add(new ItemHolder(itemId, itemCount));
}
}));
}
public List<ItemHolder> getRewards()
{
return _rewards;
}
public int getRewardsCount()
{
return _rewardsCount;
}
public static AttendanceRewardData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final AttendanceRewardData _instance = new AttendanceRewardData();
}
}

View File

@ -63,6 +63,7 @@ import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
import com.l2jmobius.gameserver.data.sql.impl.CharSummonTable;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.data.xml.impl.ClassListData;
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import com.l2jmobius.gameserver.data.xml.impl.HennaData;
@ -207,6 +208,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerPvPCh
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerPvPKill;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerReputationChanged;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerSubChange;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.holders.MovieHolder;
import com.l2jmobius.gameserver.model.holders.PlayerEventHolder;
@ -842,6 +844,10 @@ public final class L2PcInstance extends L2Playable
private final static String TRAINING_CAMP_VAR = "TRAINING_CAMP";
private final static String TRAINING_CAMP_DURATION = "TRAINING_CAMP_DURATION";
// Attendance Reward system
private final static String ATTENDANCE_DATE_VAR = "ATTENDANCE_DATE";
private final static String ATTENDANCE_INDEX_VAR = "ATTENDANCE_INDEX";
// Save responder name for log it
private String _lastPetitionGmName = null;
@ -13976,4 +13982,60 @@ public final class L2PcInstance extends L2Playable
final TrainingHolder trainingHolder = getTraingCampInfo();
return (trainingHolder != null) && (trainingHolder.getEndTime() > 0);
}
public AttendanceInfoHolder getAttendanceInfo()
{
// Get reset time.
final Calendar calendar = Calendar.getInstance();
if ((calendar.get(Calendar.HOUR_OF_DAY) < 6) && (calendar.get(Calendar.MINUTE) < 30))
{
calendar.add(Calendar.DAY_OF_MONTH, -1);
}
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// Get last player reward time.
final long receiveDate;
int rewardIndex;
if (Config.ATTENDANCE_REWARDS_SHARE_ACCOUNT)
{
receiveDate = getAccountVariables().getLong(ATTENDANCE_DATE_VAR, 0);
rewardIndex = getAccountVariables().getInt(ATTENDANCE_INDEX_VAR, 0);
}
else
{
receiveDate = getVariables().getLong(ATTENDANCE_DATE_VAR, 0);
rewardIndex = getVariables().getInt(ATTENDANCE_INDEX_VAR, 0);
}
// Check if player can receive reward today.
boolean canBeRewarded = false;
if (calendar.getTimeInMillis() > receiveDate)
{
canBeRewarded = true;
// Reset index if max is reached.
if (rewardIndex >= AttendanceRewardData.getInstance().getRewardsCount())
{
rewardIndex = 0;
}
}
return new AttendanceInfoHolder(rewardIndex, canBeRewarded);
}
public void setAttendanceInfo(int rewardIndex)
{
if (Config.ATTENDANCE_REWARDS_SHARE_ACCOUNT)
{
getAccountVariables().set(ATTENDANCE_DATE_VAR, System.currentTimeMillis());
getAccountVariables().set(ATTENDANCE_INDEX_VAR, rewardIndex);
}
else
{
getVariables().set(ATTENDANCE_DATE_VAR, System.currentTimeMillis());
getVariables().set(ATTENDANCE_INDEX_VAR, rewardIndex);
}
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.holders;
/**
* @author Mobius
*/
public class AttendanceInfoHolder
{
private final int _rewardIndex;
private final boolean _rewardAvailable;
public AttendanceInfoHolder(int rewardIndex, boolean rewardAvailable)
{
_rewardIndex = rewardIndex;
_rewardAvailable = rewardAvailable;
}
public int getRewardIndex()
{
return _rewardIndex;
}
public boolean isRewardAvailable()
{
return _rewardAvailable;
}
}

View File

@ -40,6 +40,8 @@ import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExCancel
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExTryToPutShapeShiftingEnchantSupportItem;
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestExTryToPutShapeShiftingTargetItem;
import com.l2jmobius.gameserver.network.clientpackets.appearance.RequestShapeShiftingItem;
import com.l2jmobius.gameserver.network.clientpackets.attendance.RequestVipAttendanceCheck;
import com.l2jmobius.gameserver.network.clientpackets.attendance.RequestVipAttendanceItemList;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.RequestChangeAttributeCancel;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.RequestChangeAttributeItem;
import com.l2jmobius.gameserver.network.clientpackets.attributechange.SendChangeAttributeTargetItem;
@ -349,8 +351,8 @@ public enum ExIncomingPackets implements IIncomingPackets<L2GameClient>
SEND_EXECUTED_UI_EVENTS_COUNT(0x103, null, ConnectionState.IN_GAME),
EX_SEND_CLIENT_INI(0x104, null, ConnectionState.AUTHENTICATED),
REQUEST_EX_AUTO_FISH(0x105, ExRequestAutoFish::new, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_ITEM_LIST(0x106, null, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_CHECK(0x107, null, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_ITEM_LIST(0x106, RequestVipAttendanceItemList::new, ConnectionState.IN_GAME),
REQUEST_VIP_ATTENDANCE_CHECK(0x107, RequestVipAttendanceCheck::new, ConnectionState.IN_GAME),
REQUEST_ITEM_ENSOUL(0x108, RequestItemEnsoul::new, ConnectionState.IN_GAME),
REQUEST_CASTLE_WAR_SEASON_REWARD(0x109, null, ConnectionState.IN_GAME),
REQUEST_VIP_PRODUCT_LIST(0x10A, null, ConnectionState.IN_GAME),

View File

@ -51,6 +51,7 @@ import com.l2jmobius.gameserver.model.entity.Fort;
import com.l2jmobius.gameserver.model.entity.FortSiege;
import com.l2jmobius.gameserver.model.entity.L2Event;
import com.l2jmobius.gameserver.model.entity.Siege;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.instancezone.Instance;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.quest.Quest;
@ -98,6 +99,7 @@ import com.l2jmobius.gameserver.network.serverpackets.SkillCoolTime;
import com.l2jmobius.gameserver.network.serverpackets.SkillList;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.ability.ExAcquireAPSkillList;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList;
import com.l2jmobius.gameserver.network.serverpackets.dailymission.ExOneDayReceiveRewardList;
import com.l2jmobius.gameserver.network.serverpackets.friend.L2FriendList;
@ -653,6 +655,26 @@ public class EnterWorld implements IClientIncomingPacket
activeChar.updateAbnormalVisualEffects();
}
if (Config.ENABLE_ATTENDANCE_REWARDS)
{
ThreadPoolManager.schedule(() ->
{
// Check if player can receive reward today.
final AttendanceInfoHolder attendanceInfo = activeChar.getAttendanceInfo();
if (attendanceInfo.isRewardAvailable())
{
final int lastRewardIndex = attendanceInfo.getRewardIndex() + 1;
activeChar.sendPacket(new ExShowScreenMessage("Your attendance day " + lastRewardIndex + " reward is ready.", ExShowScreenMessage.TOP_CENTER, 7000, 0, true, true));
activeChar.sendMessage("Your attendance day " + lastRewardIndex + " reward is ready.");
activeChar.sendMessage("Click on General Menu -> Attendance Check.");
if (Config.ATTENDANCE_POPUP_WINDOW)
{
activeChar.sendPacket(new ExVipAttendanceItemList(activeChar));
}
}
}, Config.ATTENDANCE_REWARD_DELAY * 60 * 1000);
}
if (Config.HARDWARE_INFO_ENABLED)
{
ThreadPoolManager.schedule(() ->

View File

@ -0,0 +1,103 @@
/*
* 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.network.clientpackets.attendance;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExConfirmVipAttendanceCheck;
/**
* @author Mobius
*/
public class RequestVipAttendanceCheck implements IClientIncomingPacket
{
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(L2GameClient client)
{
final L2PcInstance activeChar = client.getActiveChar();
if (activeChar == null)
{
return;
}
if (!Config.ENABLE_ATTENDANCE_REWARDS)
{
activeChar.sendPacket(SystemMessageId.DUE_TO_A_SYSTEM_ERROR_THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_PLEASE_TRY_AGAIN_LATER_BY_GOING_TO_MENU_ATTENDANCE_CHECK);
return;
}
if (Config.PREMIUM_ONLY_ATTENDANCE_REWARDS && !activeChar.hasPremiumStatus())
{
activeChar.sendPacket(SystemMessageId.YOUR_VIP_RANK_IS_TOO_LOW_TO_RECEIVE_THE_REWARD);
return;
}
// Check login delay.
if (activeChar.getUptime() < (Config.ATTENDANCE_REWARD_DELAY * 60 * 1000))
{
// activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_LEVEL_REQUIREMENTS_TO_RECEIVE_THE_ATTENDANCE_REWARD_PLEASE_CHECK_THE_REQUIRED_LEVEL_YOU_CAN_REDEEM_YOUR_REWARD_30_MINUTES_AFTER_LOGGING_IN);
activeChar.sendMessage("You can redeem your reward " + Config.ATTENDANCE_REWARD_DELAY + " minutes after logging in.");
return;
}
final AttendanceInfoHolder attendanceInfo = activeChar.getAttendanceInfo();
final boolean isRewardAvailable = attendanceInfo.isRewardAvailable();
final int rewardIndex = attendanceInfo.getRewardIndex();
final ItemHolder reward = AttendanceRewardData.getInstance().getRewards().get(rewardIndex);
final L2Item itemTemplate = ItemTable.getInstance().getTemplate(reward.getId());
// Weight check.
final long weight = itemTemplate.getWeight() * reward.getCount();
final long slots = itemTemplate.isStackable() ? 1 : reward.getCount();
if (!activeChar.getInventory().validateWeight(weight) || !activeChar.getInventory().validateCapacity(slots))
{
activeChar.sendPacket(SystemMessageId.THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_BECAUSE_THE_INVENTORY_WEIGHT_QUANTITY_LIMIT_HAS_BEEN_EXCEEDED);
return;
}
// Reward.
if (isRewardAvailable)
{
// Save date and index.
activeChar.setAttendanceInfo(rewardIndex + 1);
// Add items to player.
activeChar.addItem("Attendance Reward", reward, activeChar, true);
// Send message.
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_VE_RECEIVED_YOUR_VIP_ATTENDANCE_REWARD_FOR_DAY_S1);
msg.addInt(rewardIndex + 1);
activeChar.sendPacket(msg);
// Send confirm packet.
activeChar.sendPacket(new ExConfirmVipAttendanceCheck(isRewardAvailable, rewardIndex + 1));
}
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.network.clientpackets.attendance;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import com.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList;
/**
* @author Mobius
*/
public class RequestVipAttendanceItemList implements IClientIncomingPacket
{
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(L2GameClient client)
{
final L2PcInstance activeChar = client.getActiveChar();
if (activeChar == null)
{
return;
}
if (!Config.ENABLE_ATTENDANCE_REWARDS)
{
activeChar.sendPacket(SystemMessageId.DUE_TO_A_SYSTEM_ERROR_THE_ATTENDANCE_REWARD_CANNOT_BE_RECEIVED_PLEASE_TRY_AGAIN_LATER_BY_GOING_TO_MENU_ATTENDANCE_CHECK);
return;
}
activeChar.sendPacket(new ExVipAttendanceItemList(activeChar));
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.network.serverpackets.attendance;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.network.OutgoingPackets;
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* @author Mobius
*/
public class ExConfirmVipAttendanceCheck implements IClientOutgoingPacket
{
boolean _available;
int _index;
public ExConfirmVipAttendanceCheck(boolean rewardAvailable, int rewardIndex)
{
_available = rewardAvailable;
_index = rewardIndex;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_CONFIRM_VIP_ATTENDANCE_CHECK.writeId(packet);
packet.writeC(_available ? 0x01 : 0x00); // can receive reward today? 1 else 0
packet.writeC(_index); // active reward index
packet.writeD(0);
packet.writeD(0);
return true;
}
}

View File

@ -0,0 +1,67 @@
/*
* 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.network.serverpackets.attendance;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.data.xml.impl.AttendanceRewardData;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.network.OutgoingPackets;
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* @author Mobius
*/
public class ExVipAttendanceItemList implements IClientOutgoingPacket
{
boolean _available;
int _index;
public ExVipAttendanceItemList(L2PcInstance player)
{
final AttendanceInfoHolder attendanceInfo = player.getAttendanceInfo();
_available = attendanceInfo.isRewardAvailable();
_index = attendanceInfo.getRewardIndex();
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_VIP_ATTENDANCE_ITEM_LIST.writeId(packet);
packet.writeC(_available ? _index + 1 : _index); // index to receive?
packet.writeC(_index); // last received index?
packet.writeD(0x00);
packet.writeD(0x00);
packet.writeC(0x01);
packet.writeC(_available ? 0x01 : 0x00); // player can receive reward today?
packet.writeC(250);
packet.writeC(AttendanceRewardData.getInstance().getRewardsCount()); // reward size
int rewardCounter = 0;
for (ItemHolder reward : AttendanceRewardData.getInstance().getRewards())
{
rewardCounter++;
packet.writeD(reward.getId());
packet.writeQ(reward.getCount());
packet.writeC(0x01); // is unknown?
packet.writeC((rewardCounter % 7) == 0 ? 0x01 : 0x00); // is last in row?
}
packet.writeC(0x00);
packet.writeD(0x00);
return true;
}
}

View File

@ -47,14 +47,16 @@ What is done
-Augmentation chances from L2Wiki
-Working Runes system
-Added new Savior skills
-Dungeon of Abyss
-Attendance rewards
Custom work
-Newbie Helper NPC location info
-Newbie Helper buff support until 40 level
-Test Server Helper NPCs
-Fake players engine
TODO list
-Parse retail monster spawns by zone
-Test quests and update rewards
-Dungeon of Abyss https://www.youtube.com/watch?v=FZEu0hjCAK8
-Provisional Clan Halls