feat: bug fix social system

This commit is contained in:
2026-04-30 04:18:46 +08:00
parent 2a1a76e682
commit 54be7bbb25
9 changed files with 607 additions and 235 deletions
+109
View File
@@ -23,6 +23,7 @@ function InitModule(ctx, logger, nk, initializer) {
// User management RPCs
initializer.registerRpc("get_user_profile", rpcGetUserProfile);
initializer.registerRpc("update_user_profile", rpcUpdateUserProfile);
initializer.registerRpc("search_users", rpcSearchUsers);
// Store RPCs
initializer.registerRpc("purchase_item", rpcPurchaseItem);
@@ -40,6 +41,7 @@ function InitModule(ctx, logger, nk, initializer) {
initializer.registerRpc("change_credentials", rpcChangeCredentials);
initializer.registerRpc("reset_stats", rpcResetStats);
initializer.registerRpc("send_lobby_invite", rpcSendLobbyInvite);
initializer.registerRpc("send_friend_request", rpcSendFriendRequest);
// Steam auth hooks
initializer.registerAfterAuthenticateSteam(afterAuthenticateSteam);
@@ -661,6 +663,52 @@ function rpcUpdateUserProfile(ctx, logger, nk, payload) {
}
}
function rpcSearchUsers(ctx, logger, nk, payload) {
if (!ctx.userId) {
throw new Error("Not authenticated");
}
var request = {};
try {
request = JSON.parse(payload || "{}");
} catch (e) {}
var query = request.query || "";
try {
var users = [];
var sql = "";
var params = [];
if (query === "") {
sql = "SELECT id, username, display_name, metadata FROM users WHERE id != '00000000-0000-0000-0000-000000000000' ORDER BY create_time DESC LIMIT 100";
} else {
sql = "SELECT id, username, display_name, metadata FROM users WHERE (username ILIKE $1 OR display_name ILIKE $1) AND id != '00000000-0000-0000-0000-000000000000' ORDER BY create_time DESC LIMIT 100";
params = ["%" + query + "%"];
}
var rows = nk.sqlQuery(sql, params);
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
var metadata = {};
try { metadata = JSON.parse(row.metadata || "{}"); } catch(e) {}
users.push({
user_id: row.id,
username: row.username || "",
display_name: row.display_name || row.username || "",
avatar_url: metadata.avatar_url || ""
});
}
return JSON.stringify({ users: users });
} catch (e) {
logger.error("Failed to search users: " + e);
return JSON.stringify({ users: [] });
}
}
// =============================================================================
// Leaderboard RPCs
// =============================================================================
@@ -1091,3 +1139,64 @@ function beforeAuthenticateEmail(ctx, logger, nk, data) {
// Can't check ban before auth, so we check in afterAuthenticate
return data;
}
// =============================================================================
// Social / Friend RPCs
// =============================================================================
// Sends a real-time notification (code 1002) to the target so their client
// can refresh the friends list immediately. The actual friend relationship
// is added by the client via add_friends_async BEFORE calling this RPC.
function rpcSendFriendRequest(ctx, logger, nk, payload) {
if (!ctx.userId) throw new Error("Not authenticated");
var request = {};
try { request = JSON.parse(payload || "{}"); } catch (e) {}
var targetUserId = request.user_id || "";
if (!targetUserId) throw new Error("user_id is required");
if (targetUserId === ctx.userId) throw new Error("Cannot add yourself");
var senderAccount = nk.accountGetId(ctx.userId);
var senderName = senderAccount.user.displayName || senderAccount.user.username || "Someone";
// Send a persistent notification to target so they see it on next login too
nk.notificationSend(
targetUserId,
"Friend Request",
{ from_user_id: ctx.userId, from_name: senderName },
1002, // code: friend request
ctx.userId, // sender
true // persistent (survives offline)
);
logger.info("Friend request notification sent from " + ctx.userId + " to " + targetUserId);
return JSON.stringify({ success: true });
}
function rpcSendLobbyInvite(ctx, logger, nk, payload) {
if (!ctx.userId) throw new Error("Not authenticated");
var request = {};
try { request = JSON.parse(payload || "{}"); } catch (e) {}
var toUserId = request.to_user_id || "";
var matchId = request.match_id || "";
if (!toUserId) throw new Error("to_user_id is required");
if (!matchId) throw new Error("match_id is required");
var senderAccount = nk.accountGetId(ctx.userId);
var senderName = senderAccount.user.displayName || senderAccount.user.username || "Someone";
nk.notificationSend(
toUserId,
"Lobby Invite",
{ from_name: senderName, match_id: matchId },
1001, // code: 1001 = lobby invite
ctx.userId,
false // not persistent
);
logger.info("Lobby invite sent from " + ctx.userId + " to " + toUserId + " for match " + matchId);
return JSON.stringify({ success: true });
}