mirror of
https://github.com/Melledy/Nebula.git
synced 2026-11-04 21:36:51 +01:00
Implement anniversary sign in events
This commit is contained in:
1 parent
f5bdee5df3
commit
c9e62500ad
11 files changed
+272
-3
No files matched your search
@@ -57,6 +57,7 @@ public class GameData {
|
||||
@Getter private static DataTable<MallPackageDef> MallPackageDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<MallShopDef> MallShopDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<MallGemDef> MallGemDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<MallActivityDef> MallActivityDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<MonthlyCardRewardDef> MonthlyCardRewardDataTable = new DataTable<>();
|
||||
|
||||
@Getter private static DataTable<ResidentShopDef> ResidentShopDataTable = new DataTable<>();
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "MallActivity.json")
|
||||
public class MallActivityDef extends BaseDef {
|
||||
@SerializedName("Id")
|
||||
private String IdString;
|
||||
private String Name;
|
||||
private int Price;
|
||||
private String ShowPrice;
|
||||
private int ActivityId;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return IdString.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -140,6 +140,8 @@ public class ActivityManager extends PlayerManager implements GameDatabaseObject
|
||||
case Story -> new StoryActivity(this, data);
|
||||
case PenguinCard -> new PenguinCardActivity(this, data);
|
||||
case Soldier -> new SoldierActivity(this, data);
|
||||
case MallLogin -> new MallLoginActivity(this, data);
|
||||
case SignIn -> new SignInActivity(this, data);
|
||||
default -> null;
|
||||
};
|
||||
|
||||
|
||||
@@ -122,6 +122,12 @@ public class ActivityModule extends GameContextModule {
|
||||
|
||||
// Trekker versus (broken)
|
||||
//this.activities.add(600001);
|
||||
|
||||
// 1st anniversary
|
||||
this.activities.add(301051);
|
||||
this.activities.add(301052);
|
||||
this.activities.add(301053);
|
||||
this.activities.add(302001);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public class LoginRewardActivity extends GameActivity {
|
||||
super(manager, data);
|
||||
}
|
||||
|
||||
public PlayerChangeInfo claim() {
|
||||
public synchronized PlayerChangeInfo claim() {
|
||||
// Create change info
|
||||
var change = new PlayerChangeInfo();
|
||||
|
||||
@@ -64,7 +64,7 @@ public class LoginRewardActivity extends GameActivity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogin() {
|
||||
public synchronized void onLogin() {
|
||||
// Check if epoch day has changed
|
||||
if (this.getPlayer().getLastEpochDay() <= this.lastEpochDay || this.isComplete()) {
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
package emu.nebula.game.activity.type;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.data.resources.ActivityDef;
|
||||
import emu.nebula.game.activity.ActivityManager;
|
||||
import emu.nebula.game.activity.GameActivity;
|
||||
import emu.nebula.game.inventory.ItemParamMap;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
import emu.nebula.proto.ActivityDetail.ActivityMsg;
|
||||
import emu.nebula.util.Utils;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Mall check-in activity
|
||||
* <p>
|
||||
* These activities are shown inside of the mall instead of the regular activity list and
|
||||
* they use their own protocol message (ActivityMallLogin). Next to the amount of unlocked
|
||||
* check-in days and the amount of claimed rewards, that message also carries an "active"
|
||||
* (purchased) flag which tells the client if the check-in can be claimed at all.
|
||||
* <p>
|
||||
* The rewards are the same as the ones used by the login reward activities, they are stored
|
||||
* in the LoginRewardGroup table using the activity id as a prefix (activityId * 100 + day).
|
||||
*/
|
||||
@Getter
|
||||
@Entity
|
||||
public class MallLoginActivity extends GameActivity {
|
||||
// Whether the check-in is active for this player
|
||||
private boolean active;
|
||||
// Amount of check-in days that have been unlocked
|
||||
private int loginDays;
|
||||
// Amount of check-in rewards that have been claimed
|
||||
private int received;
|
||||
// Last day the check-in was advanced on
|
||||
private long lastEpochDay;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public MallLoginActivity() {
|
||||
|
||||
}
|
||||
|
||||
public MallLoginActivity(ActivityManager manager, ActivityDef data) {
|
||||
super(manager, data);
|
||||
}
|
||||
|
||||
// Events
|
||||
|
||||
@Override
|
||||
public synchronized void onLogin() {
|
||||
long epochDay = Utils.getResetEpochDay();
|
||||
|
||||
// Check if a new day started since the last login
|
||||
if (epochDay <= this.lastEpochDay) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Unlock the next check-in day
|
||||
int nextLoginDay = this.loginDays + 1;
|
||||
var data = GameData.getLoginRewardGroupControlDataTable().get((this.getId() * 100) + nextLoginDay);
|
||||
|
||||
if (data != null) {
|
||||
this.loginDays = nextLoginDay;
|
||||
}
|
||||
|
||||
// Update the last day and save to database
|
||||
this.lastEpochDay = epochDay;
|
||||
this.save();
|
||||
}
|
||||
|
||||
// Rewards
|
||||
|
||||
public synchronized PlayerChangeInfo claim() {
|
||||
// Create change info
|
||||
var change = new PlayerChangeInfo();
|
||||
|
||||
// Sanity check
|
||||
if (!this.isActive() || this.getReceived() >= this.getLoginDays()) {
|
||||
return change;
|
||||
}
|
||||
|
||||
// Get rewards
|
||||
var rewards = new ItemParamMap();
|
||||
|
||||
for (int i = this.getReceived() + 1; i <= this.getLoginDays(); i++) {
|
||||
int rewardId = (this.getId() * 100) + i;
|
||||
var data = GameData.getLoginRewardGroupControlDataTable().get(rewardId);
|
||||
|
||||
if (data == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rewards.add(data.getRewards());
|
||||
}
|
||||
|
||||
// Give rewards to player
|
||||
this.getPlayer().getInventory().addItems(rewards, change);
|
||||
|
||||
// Update claimed and save to database
|
||||
this.received = this.loginDays;
|
||||
this.save();
|
||||
|
||||
// Complete
|
||||
return change;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
@Override
|
||||
public void encodeActivityMsg(ActivityMsg msg) {
|
||||
msg.getMutableMallLogin()
|
||||
.setActivityId(this.getId())
|
||||
.setActive(this.isActive())
|
||||
.setLoginDays(this.getLoginDays())
|
||||
.setReceived(this.getReceived());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package emu.nebula.game.activity.type;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
|
||||
import emu.nebula.data.resources.ActivityDef;
|
||||
import emu.nebula.game.activity.ActivityManager;
|
||||
|
||||
/**
|
||||
* Sign-in activity
|
||||
* <p>
|
||||
* The client does not distinguish sign-in activities from login reward activities, both
|
||||
* activity types are handled by the same login reward data class, they share the same
|
||||
* protocol message (ActivityLogin) and they are both claimed with the same request.
|
||||
* <p>
|
||||
* Because of that this activity only exists to give sign-in activities their own
|
||||
* activity type, all of the actual logic is inherited from the login reward activity.
|
||||
*/
|
||||
@Entity
|
||||
public class SignInActivity extends LoginRewardActivity {
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public SignInActivity() {
|
||||
|
||||
}
|
||||
|
||||
public SignInActivity(ActivityManager manager, ActivityDef data) {
|
||||
super(manager, data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -863,6 +863,9 @@ public class Player implements GameDatabaseObject {
|
||||
// See if we need to reset dailies
|
||||
this.checkResetDailies();
|
||||
|
||||
// Update the activities (login rewards, sign-ins, etc)
|
||||
this.getActivityManager().onLogin();
|
||||
|
||||
// Try to update trace hunt control
|
||||
if (this.getTraceHuntManager().updateControl()) {
|
||||
this.getTraceHuntManager().save();
|
||||
|
||||
@@ -15,8 +15,12 @@ public class HandlerActivityLoginRewardReceiveReq extends NetHandler {
|
||||
// Parse request
|
||||
var req = UI32.parseFrom(message);
|
||||
|
||||
// Get activity id from request
|
||||
int activityId = req.getValue();
|
||||
|
||||
// Get activity
|
||||
var activity = session.getPlayer().getActivityManager().getActivity(LoginRewardActivity.class, req.getValue());
|
||||
// Note: Sign-in activities are handled by the same request as the login reward activities
|
||||
var activity = session.getPlayer().getActivityManager().getActivity(LoginRewardActivity.class, activityId);
|
||||
|
||||
if (activity == null) {
|
||||
return session.encodeMsg(NetMsgId.activity_login_reward_receive_failed_ack);
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.game.activity.type.MallLoginActivity;
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.Public.UI32;
|
||||
|
||||
@HandlerId(NetMsgId.activity_malllogin_reward_receive_req)
|
||||
public class HandlerActivityMallLoginRewardReceiveReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = UI32.parseFrom(message);
|
||||
|
||||
// Get activity
|
||||
var activity = session.getPlayer().getActivityManager().getActivity(MallLoginActivity.class, req.getValue());
|
||||
|
||||
if (activity == null) {
|
||||
return session.encodeMsg(NetMsgId.activity_malllogin_reward_receive_failed_ack);
|
||||
}
|
||||
|
||||
// Claim any rewards
|
||||
var change = activity.claim();
|
||||
|
||||
if (change == null) {
|
||||
return session.encodeMsg(NetMsgId.activity_malllogin_reward_receive_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.activity_malllogin_reward_receive_succeed_ack, change.toProto());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.game.activity.type.MallLoginActivity;
|
||||
import emu.nebula.net.GameSession;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.MallActivityListOuterClass.MallActivityInfo;
|
||||
import emu.nebula.proto.MallActivityListOuterClass.MallActivityList;
|
||||
|
||||
@HandlerId(NetMsgId.mall_activity_list_req)
|
||||
public class HandlerMallActivityListReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Get player
|
||||
var player = session.getPlayer();
|
||||
|
||||
// Build response
|
||||
var rsp = MallActivityList.newInstance();
|
||||
|
||||
for (var data : GameData.getMallActivityDataTable()) {
|
||||
// Get the activity that this product unlocks
|
||||
var activity = player.getActivityManager().getActivity(MallLoginActivity.class, data.getActivityId());
|
||||
|
||||
if (activity == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create proto info
|
||||
var info = MallActivityInfo.newInstance()
|
||||
.setId(data.getIdString())
|
||||
.setPurchased(activity.isActive());
|
||||
|
||||
rsp.addList(info);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.mall_activity_list_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user