mirror of
https://github.com/Melledy/Nebula.git
synced 2025-12-13 04:45:02 +01:00
Implement friends list
This commit is contained in:
@@ -101,7 +101,7 @@ public class Config {
|
||||
public boolean skipIntro = false;
|
||||
public boolean unlockInstances = true;
|
||||
public int dailyResetHour = 0;
|
||||
public int leaderboardRefreshTime = 60;
|
||||
public int leaderboardRefreshTime = 60; // Leaderboard refresh time in seconds
|
||||
public WelcomeMail welcomeMail = new WelcomeMail();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,4 +24,7 @@ public class GameConstants {
|
||||
public static final int MAX_SHOWCASE_IDS = 5;
|
||||
|
||||
public static final int BATTLE_PASS_ID = 1;
|
||||
|
||||
public static final int MAX_FRIENDSHIPS = 50;
|
||||
public static final int MAX_PENDING_FRIENDSHIPS = 30;
|
||||
}
|
||||
|
||||
311
src/main/java/emu/nebula/game/friends/FriendList.java
Normal file
311
src/main/java/emu/nebula/game/friends/FriendList.java
Normal file
@@ -0,0 +1,311 @@
|
||||
package emu.nebula.game.friends;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.game.GameContext;
|
||||
import emu.nebula.game.player.Player;
|
||||
import emu.nebula.game.player.PlayerManager;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.FriendListGet.FriendListGetResp;
|
||||
import emu.nebula.proto.Public.FriendDetail;
|
||||
import emu.nebula.proto.Public.FriendState;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class FriendList extends PlayerManager {
|
||||
private final Int2ObjectMap<Friendship> friends;
|
||||
private final Int2ObjectMap<Friendship> pendingFriends;
|
||||
|
||||
private long cacheCooldown;
|
||||
private FriendListGetResp cachedProto;
|
||||
|
||||
public FriendList(Player player) {
|
||||
super(player);
|
||||
this.friends = new Int2ObjectOpenHashMap<Friendship>();
|
||||
this.pendingFriends = new Int2ObjectOpenHashMap<Friendship>();
|
||||
}
|
||||
|
||||
private GameContext getGameContext() {
|
||||
return Nebula.getGameContext();
|
||||
}
|
||||
|
||||
public boolean isLoaded() {
|
||||
return this.getPlayer().isLoaded();
|
||||
}
|
||||
|
||||
private synchronized Friendship getFriendById(int id) {
|
||||
if (this.isLoaded()) {
|
||||
return this.getFriends().get(id);
|
||||
} else {
|
||||
return Nebula.getGameDatabase().getObjectByUid(Friendship.class, Friendship.generateUniqueKey(getPlayerUid(), id));
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized Friendship getPendingFriendById(int id) {
|
||||
if (this.isLoaded()) {
|
||||
return this.getPendingFriends().get(id);
|
||||
} else {
|
||||
return Nebula.getGameDatabase().getObjectByUid(Friendship.class, Friendship.generateUniqueKey(getPlayerUid(), id));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean hasPendingRequests() {
|
||||
return this.getPendingFriends().values()
|
||||
.stream()
|
||||
.filter(f -> f.getAskerUid() != this.getPlayerUid())
|
||||
.findAny()
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
private void addFriendship(Friendship friendship) {
|
||||
getFriends().put(friendship.getFriendUid(), friendship);
|
||||
this.cacheCooldown = 0;
|
||||
}
|
||||
|
||||
private void addPendingFriendship(Friendship friendship) {
|
||||
getPendingFriends().put(friendship.getFriendUid(), friendship);
|
||||
this.cacheCooldown = 0;
|
||||
}
|
||||
|
||||
private void removeFriendship(int uid) {
|
||||
getFriends().remove(uid);
|
||||
this.cacheCooldown = 0;
|
||||
}
|
||||
|
||||
private void removePendingFriendship(int uid) {
|
||||
getPendingFriends().remove(uid);
|
||||
this.cacheCooldown = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets total amount of potential friends
|
||||
*/
|
||||
public int getFullFriendCount() {
|
||||
return this.getPendingFriends().size() + this.getFriends().size();
|
||||
}
|
||||
|
||||
public synchronized Player handleFriendRequest(int targetUid, boolean action) {
|
||||
// Make sure we have enough room
|
||||
if (this.getFriends().size() >= GameConstants.MAX_FRIENDSHIPS) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if player has sent friend request
|
||||
Friendship myFriendship = this.getPendingFriendById(targetUid);
|
||||
if (myFriendship == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Make sure this player is not the asker
|
||||
if (myFriendship.getAskerUid() == this.getPlayer().getUid()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get target player
|
||||
Player target = getGameContext().getPlayerModule().getPlayer(targetUid);
|
||||
if (target == null) return null;
|
||||
|
||||
// Get target player's friendship
|
||||
Friendship theirFriendship = target.getFriendList().getPendingFriendById(getPlayer().getUid());
|
||||
|
||||
if (theirFriendship == null) {
|
||||
// They dont have us on their friends list anymore, rip
|
||||
this.removePendingFriendship(target.getUid());
|
||||
myFriendship.delete();
|
||||
return null;
|
||||
}
|
||||
|
||||
// Handle action
|
||||
if (action) {
|
||||
// Request accepted
|
||||
myFriendship.setFriend(true);
|
||||
theirFriendship.setFriend(true);
|
||||
|
||||
this.removePendingFriendship(myFriendship.getFriendUid());
|
||||
this.addFriendship(myFriendship);
|
||||
|
||||
if (target.isLoaded()) {
|
||||
target.getFriendList().removePendingFriendship(this.getPlayer().getUid());
|
||||
target.getFriendList().addFriendship(theirFriendship);
|
||||
}
|
||||
|
||||
// Save friendships to the database
|
||||
myFriendship.save();
|
||||
theirFriendship.save();
|
||||
} else {
|
||||
// Request declined - Delete from my pending friends
|
||||
this.removePendingFriendship(myFriendship.getOwnerUid());
|
||||
|
||||
if (target.isLoaded()) {
|
||||
target.getFriendList().removePendingFriendship(getPlayer().getUid());
|
||||
}
|
||||
|
||||
// Delete friendships from the database
|
||||
myFriendship.delete();
|
||||
theirFriendship.delete();
|
||||
}
|
||||
|
||||
// Success
|
||||
return target;
|
||||
}
|
||||
|
||||
public List<Player> acceptAll() {
|
||||
// Results
|
||||
List<Player> results = new ArrayList<>();
|
||||
|
||||
// Get list of friendships to accept
|
||||
List<Friendship> list = getPendingFriends().values()
|
||||
.stream()
|
||||
.toList();
|
||||
|
||||
for (var invite : list) {
|
||||
var target = this.handleFriendRequest(invite.getFriendUid(), true);
|
||||
|
||||
if (target != null) {
|
||||
results.add(target);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public synchronized boolean sendFriendRequest(int targetUid) {
|
||||
// Get target and sanity check
|
||||
Player target = getGameContext().getPlayerModule().getPlayer(targetUid);
|
||||
if (target == null || target == this.getPlayer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if friend already exists
|
||||
if (getPendingFriends().containsKey(targetUid) || getFriends().containsKey(targetUid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create friendships
|
||||
Friendship myFriendship = new Friendship(getPlayer(), target, getPlayer());
|
||||
Friendship theirFriendship = new Friendship(target, getPlayer(), getPlayer());
|
||||
|
||||
// Add to our pending friendship list
|
||||
this.addPendingFriendship(myFriendship);
|
||||
|
||||
if (target.isLoaded()) {
|
||||
target.getFriendList().addPendingFriendship(theirFriendship);
|
||||
|
||||
// Send message to notify target
|
||||
target.addNextPackage(
|
||||
NetMsgId.friend_state_notify,
|
||||
FriendState.newInstance()
|
||||
.setId(this.getPlayerUid())
|
||||
.setAction(1)
|
||||
);
|
||||
}
|
||||
|
||||
// Save friendships to the database
|
||||
myFriendship.save();
|
||||
theirFriendship.save();
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean deleteFriend(int targetUid) {
|
||||
// Get friendship
|
||||
Friendship myFriendship = this.getFriendById(targetUid);
|
||||
if (myFriendship == null) return false;
|
||||
|
||||
// Remove from friends list
|
||||
this.removeFriendship(targetUid);
|
||||
myFriendship.delete();
|
||||
|
||||
// Delete from friend's friend list
|
||||
Player friend = getGameContext().getPlayerModule().getPlayer(targetUid);
|
||||
|
||||
if (friend != null) {
|
||||
// Friend online
|
||||
Friendship theirFriendship = friend.getFriendList().getFriendById(this.getPlayer().getUid());
|
||||
|
||||
if (theirFriendship != null) {
|
||||
// Delete friendship on friends side
|
||||
theirFriendship.delete();
|
||||
|
||||
if (friend.isLoaded()) {
|
||||
// Remove from online friend's friend list
|
||||
friend.getFriendList().removeFriendship(theirFriendship.getFriendUid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
// Database
|
||||
|
||||
public synchronized void loadFromDatabase() {
|
||||
var friendships = Nebula.getGameDatabase().getObjects(Friendship.class, "ownerUid", this.getPlayer().getUid());
|
||||
|
||||
friendships.forEach(friendship -> {
|
||||
// Set ownership first
|
||||
friendship.setOwner(getPlayer());
|
||||
|
||||
// Finally, load to our friends list
|
||||
if (friendship.isFriend()) {
|
||||
getFriends().put(friendship.getFriendUid(), friendship);
|
||||
} else {
|
||||
getPendingFriends().put(friendship.getFriendUid(), friendship);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public synchronized FriendListGetResp toProto() {
|
||||
if (this.cachedProto == null || System.currentTimeMillis() > this.cacheCooldown) {
|
||||
this.cachedProto = this.updateCache();
|
||||
this.cacheCooldown = System.currentTimeMillis() + 60_000;
|
||||
}
|
||||
|
||||
return this.cachedProto;
|
||||
}
|
||||
|
||||
private FriendListGetResp updateCache() {
|
||||
var proto = FriendListGetResp.newInstance();
|
||||
|
||||
// Encode friends list
|
||||
for (var friend : getFriends().values()) {
|
||||
// Get base friend info
|
||||
var base = friend.toProto();
|
||||
if (base == null) continue;
|
||||
|
||||
// Create info
|
||||
var info = FriendDetail.newInstance()
|
||||
.setBase(base)
|
||||
.setGetEnergy(friend.getEnergy());
|
||||
|
||||
// Add
|
||||
proto.addFriends(info);
|
||||
}
|
||||
|
||||
// Encode pending invites
|
||||
for (var friend : getPendingFriends().values()) {
|
||||
// Skip if this is us
|
||||
if (friend.getAskerUid() == this.getPlayerUid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get base friend info
|
||||
var base = friend.toProto();
|
||||
if (base == null) continue;
|
||||
|
||||
// Add
|
||||
proto.addInvites(base);
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
65
src/main/java/emu/nebula/game/friends/Friendship.java
Normal file
65
src/main/java/emu/nebula/game/friends/Friendship.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package emu.nebula.game.friends;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import dev.morphia.annotations.Indexed;
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.database.GameDatabaseObject;
|
||||
import emu.nebula.game.player.Player;
|
||||
import emu.nebula.proto.Public.Friend;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Entity(value = "friendships", useDiscriminator = false)
|
||||
public class Friendship implements GameDatabaseObject {
|
||||
@Id private long key;
|
||||
|
||||
@Indexed private int ownerUid;
|
||||
@Indexed private int friendUid;
|
||||
private int askerUid;
|
||||
|
||||
@Setter
|
||||
private boolean isFriend;
|
||||
private boolean star;
|
||||
private int energy;
|
||||
|
||||
@Setter private transient Player owner;
|
||||
|
||||
@Deprecated // Morphia use only
|
||||
public Friendship() { }
|
||||
|
||||
public Friendship(Player owner, Player friend, Player asker) {
|
||||
this.owner = owner;
|
||||
this.ownerUid = owner.getUid();
|
||||
this.friendUid = friend.getUid();
|
||||
this.askerUid = asker.getUid();
|
||||
this.key = Friendship.generateUniqueKey(owner.getUid(), friend.getUid());
|
||||
}
|
||||
|
||||
// Database functions
|
||||
|
||||
public void delete() {
|
||||
Nebula.getGameDatabase().delete(this);
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public Friend toProto() {
|
||||
// Get target player
|
||||
var target = Nebula.getGameContext().getPlayerModule().getPlayer(this.getFriendUid());
|
||||
if (target == null) return null;
|
||||
|
||||
// Encode player to simple friend proto
|
||||
return target.getFriendProto();
|
||||
}
|
||||
|
||||
// Extra
|
||||
|
||||
/**
|
||||
* Creates an unique key for a friendship object using 2 player uids
|
||||
*/
|
||||
public static long generateUniqueKey(int ownerUid, int targetUid) {
|
||||
return ((long) ownerUid << 32) + targetUid;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import emu.nebula.game.agent.AgentManager;
|
||||
import emu.nebula.game.battlepass.BattlePassManager;
|
||||
import emu.nebula.game.character.CharacterStorage;
|
||||
import emu.nebula.game.formation.FormationManager;
|
||||
import emu.nebula.game.friends.FriendList;
|
||||
import emu.nebula.game.gacha.GachaManager;
|
||||
import emu.nebula.game.infinitytower.InfinityTowerManager;
|
||||
import emu.nebula.game.instance.InstanceManager;
|
||||
@@ -34,6 +35,7 @@ import emu.nebula.proto.PlayerData.DictionaryTab;
|
||||
import emu.nebula.proto.PlayerData.PlayerInfo;
|
||||
import emu.nebula.proto.Public.CharShow;
|
||||
import emu.nebula.proto.Public.Energy;
|
||||
import emu.nebula.proto.Public.Friend;
|
||||
import emu.nebula.proto.Public.HonorInfo;
|
||||
import emu.nebula.proto.Public.NewbieInfo;
|
||||
import emu.nebula.proto.Public.QuestType;
|
||||
@@ -73,10 +75,12 @@ public class Player implements GameDatabaseObject {
|
||||
private long energyLastUpdate;
|
||||
|
||||
private long lastEpochDay;
|
||||
private long lastLogin;
|
||||
private long createTime;
|
||||
|
||||
// Managers
|
||||
private final transient CharacterStorage characters;
|
||||
private final transient FriendList friendList;
|
||||
private final transient GachaManager gachaManager;
|
||||
private final transient BattlePassManager battlePassManager;
|
||||
private final transient StarTowerManager starTowerManager;
|
||||
@@ -94,13 +98,15 @@ public class Player implements GameDatabaseObject {
|
||||
private transient QuestManager questManager;
|
||||
private transient AgentManager agentManager;
|
||||
|
||||
// Next packages
|
||||
// Extra
|
||||
private transient Stack<NetMsgPacket> nextPackages;
|
||||
private transient boolean loaded;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public Player() {
|
||||
// Init player managers
|
||||
this.characters = new CharacterStorage(this);
|
||||
this.friendList = new FriendList(this);
|
||||
this.gachaManager = new GachaManager(this);
|
||||
this.battlePassManager = new BattlePassManager(this);
|
||||
this.starTowerManager = new StarTowerManager(this);
|
||||
@@ -126,6 +132,7 @@ public class Player implements GameDatabaseObject {
|
||||
// Set basic info
|
||||
this.accountUid = account.getUid();
|
||||
this.createTime = Nebula.getCurrentTime();
|
||||
|
||||
this.name = name;
|
||||
this.signature = "";
|
||||
this.gender = gender;
|
||||
@@ -576,6 +583,7 @@ public class Player implements GameDatabaseObject {
|
||||
public void onLoad() {
|
||||
// Load from database
|
||||
this.getCharacters().loadFromDatabase();
|
||||
this.getFriendList().loadFromDatabase();
|
||||
this.getStarTowerManager().loadFromDatabase();
|
||||
this.getBattlePassManager().loadFromDatabase();
|
||||
|
||||
@@ -598,6 +606,9 @@ public class Player implements GameDatabaseObject {
|
||||
this.showChars = new int[3];
|
||||
this.save();
|
||||
}
|
||||
|
||||
// Load complete
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
public void onLogin() {
|
||||
@@ -606,6 +617,10 @@ public class Player implements GameDatabaseObject {
|
||||
|
||||
// Trigger quest login
|
||||
this.triggerQuest(QuestCondType.LoginTotal, 1);
|
||||
|
||||
// Update last login time
|
||||
this.lastLogin = System.currentTimeMillis();
|
||||
Nebula.getGameDatabase().update(this, this.getUid(), "lastLogin", this.getLastLogin());
|
||||
}
|
||||
|
||||
// Next packages
|
||||
@@ -696,7 +711,8 @@ public class Player implements GameDatabaseObject {
|
||||
|
||||
// Set player states
|
||||
var state = proto.getMutableState()
|
||||
.setStorySet(true);
|
||||
.setStorySet(true)
|
||||
.setFriend(this.getFriendList().hasPendingRequests());
|
||||
|
||||
state.getMutableMail()
|
||||
.setNew(this.getMailbox().hasNewMail());
|
||||
@@ -791,6 +807,36 @@ public class Player implements GameDatabaseObject {
|
||||
return proto;
|
||||
}
|
||||
|
||||
public Friend getFriendProto() {
|
||||
var proto = Friend.newInstance()
|
||||
.setId(this.getUid())
|
||||
.setWorldClass(this.getLevel())
|
||||
.setHeadIcon(this.getHeadIcon())
|
||||
.setNickName(this.getName())
|
||||
.setSignature(this.getSignature())
|
||||
.setTitlePrefix(this.getTitlePrefix())
|
||||
.setTitleSuffix(this.getTitleSuffix())
|
||||
.setLastLoginTime(this.getLastLogin() * 1_000_000L);
|
||||
|
||||
for (int charId : this.getShowChars()) {
|
||||
var info = CharShow.newInstance()
|
||||
.setCharId(charId)
|
||||
.setLevel(1) // TODO
|
||||
.setSkin((charId * 100) + 1); // TODO
|
||||
|
||||
proto.addCharShows(info);
|
||||
}
|
||||
|
||||
for (int honorId : this.getHonor()) {
|
||||
var info = HonorInfo.newInstance()
|
||||
.setId(honorId);
|
||||
|
||||
proto.addHonors(info);
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
public Energy getEnergyProto() {
|
||||
long nextDuration = Math.max(GameConstants.ENERGY_REGEN_TIME - (Nebula.getCurrentTime() - getEnergyLastUpdate()), 1);
|
||||
|
||||
|
||||
@@ -49,12 +49,30 @@ public class PlayerModule extends GameContextModule {
|
||||
return getCachedPlayers().get(uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a player object with the given uid. Returns null if the player doesnt exist.
|
||||
* Warning: Does NOT cache or load the playerdata if the player was loaded from the database.
|
||||
* @param uid User id of the player
|
||||
* @return
|
||||
*/
|
||||
public synchronized Player getPlayer(int uid) {
|
||||
// Get player from cache
|
||||
Player player = this.cachedPlayers.get(uid);
|
||||
|
||||
if (player == null) {
|
||||
// Retrieve player object from database if its not there
|
||||
player = Nebula.getGameDatabase().getObjectByUid(Player.class, uid);
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a player object with the given account. Returns null if the player doesnt exist.
|
||||
* @param uid User id of the player
|
||||
* @return
|
||||
*/
|
||||
public synchronized Player getPlayerByAccount(Account account) {
|
||||
public synchronized Player loadPlayer(Account account) {
|
||||
// Get player from cache
|
||||
Player player = this.cachedPlayersByAccount.get(account.getUid());
|
||||
|
||||
@@ -108,12 +126,17 @@ public class PlayerModule extends GameContextModule {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of recent players that have logged on (for followers)
|
||||
* Returns a list of recent players that have logged on
|
||||
* @param player Player that requested this
|
||||
*/
|
||||
public synchronized List<Player> getRandomPlayerList(Player player) {
|
||||
List<Player> list = getCachedPlayers().values().stream().filter(p -> p != player).collect(Collectors.toList());
|
||||
List<Player> list = getCachedPlayers().values().stream()
|
||||
.filter(p -> p != player)
|
||||
.limit(10)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Collections.shuffle(list);
|
||||
return list.stream().limit(15).toList();
|
||||
|
||||
return list.stream().toList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ public class GameSession {
|
||||
|
||||
// Note: We should cache players in case multiple sessions try to login to the same player at the time
|
||||
// Get player by account
|
||||
var player = Nebula.getGameContext().getPlayerModule().getPlayerByAccount(account);
|
||||
var player = Nebula.getGameContext().getPlayerModule().loadPlayer(account);
|
||||
|
||||
// Skip intro
|
||||
if (player == null && Nebula.getConfig().getServerOptions().skipIntro) {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.FriendAddAgree.FriendAddAgreeReq;
|
||||
import emu.nebula.proto.FriendAddAgree.FriendAddAgreeResp;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.friend_add_agree_req)
|
||||
public class HandlerFriendAddAgreeReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = FriendAddAgreeReq.parseFrom(message);
|
||||
|
||||
// Handle friend request
|
||||
var target = session.getPlayer().getFriendList().handleFriendRequest((int) req.getUId(), true);
|
||||
|
||||
if (target == null) {
|
||||
return session.encodeMsg(NetMsgId.friend_add_agree_failed_ack);
|
||||
}
|
||||
|
||||
// Build response
|
||||
var rsp = FriendAddAgreeResp.newInstance()
|
||||
.setFriend(target.getFriendProto());
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.friend_add_agree_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.FriendAdd.FriendAddReq;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.friend_add_req)
|
||||
public class HandlerFriendAddReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = FriendAddReq.parseFrom(message);
|
||||
int uid = (int) req.getUId();
|
||||
|
||||
// Send friend request
|
||||
boolean success = session.getPlayer().getFriendList().sendFriendRequest(uid);
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(success ? NetMsgId.friend_add_succeed_ack : NetMsgId.friend_add_failed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.FriendAllAgree.FriendAllAgreeResp;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.friend_all_agree_req)
|
||||
public class HandlerFriendAllAgreeReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Agree to all friend requests
|
||||
var results = session.getPlayer().getFriendList().acceptAll();
|
||||
|
||||
// Scuffed way of getting friend data
|
||||
var proto = session.getPlayer().getFriendList().getCachedProto();
|
||||
|
||||
// Build response
|
||||
var rsp = FriendAllAgreeResp.newInstance();
|
||||
|
||||
for (var f : results) {
|
||||
rsp.addFriends(f.getFriendProto());
|
||||
}
|
||||
|
||||
for (var i : proto.getInvites()) {
|
||||
rsp.addInvites(i);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.friend_all_agree_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.FriendDelete.FriendDeleteReq;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.friend_delete_req)
|
||||
public class HandlerFriendDeleteReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = FriendDeleteReq.parseFrom(message);
|
||||
|
||||
// Delete friend
|
||||
boolean success = session.getPlayer().getFriendList().deleteFriend((int) req.getUId());
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(success ? NetMsgId.friend_delete_succeed_ack : NetMsgId.friend_delete_failed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.FriendInvitesDelete.FriendInvitesDeleteReq;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.friend_invites_delete_req)
|
||||
public class HandlerFriendInvitesDeleteReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = FriendInvitesDeleteReq.parseFrom(message);
|
||||
|
||||
// Delete all invites
|
||||
for (long uid : req.getMutableUIds()) {
|
||||
session.getPlayer().getFriendList().handleFriendRequest((int) uid, false);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.friend_invites_delete_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.FriendListGet.FriendListGetResp;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@@ -11,8 +10,10 @@ public class HandlerFriendListGetReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
var rsp = FriendListGetResp.newInstance();
|
||||
// Build response
|
||||
var rsp = session.getPlayer().getFriendList().toProto();
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.friend_list_get_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.FriendRecommendationGet.FriendRecommendationGetResp;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.friend_recommendation_get_req)
|
||||
public class HandlerFriendRecommendationGetReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Build response
|
||||
var rsp = FriendRecommendationGetResp.newInstance();
|
||||
|
||||
// Get players
|
||||
var players = Nebula.getGameContext().getPlayerModule().getRandomPlayerList(session.getPlayer());
|
||||
|
||||
for (var player : players) {
|
||||
rsp.addFriends(player.getFriendProto());
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.friend_recommendation_get_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.FriendUidSearch.FriendUIdSearchReq;
|
||||
import emu.nebula.proto.FriendUidSearch.FriendUIdSearchResp;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.friend_uid_search_req)
|
||||
public class HandlerFriendUidSearchReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = FriendUIdSearchReq.parseFrom(message);
|
||||
int uid = (int) req.getId();
|
||||
|
||||
// Get target player
|
||||
var target = Nebula.getGameContext().getPlayerModule().getPlayer(uid);
|
||||
|
||||
if (target == null) {
|
||||
return session.encodeMsg(NetMsgId.friend_uid_search_failed_ack);
|
||||
}
|
||||
|
||||
// Build response
|
||||
var rsp = FriendUIdSearchResp.newInstance()
|
||||
.setFriend(target.getFriendProto());
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.friend_uid_search_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user