Fix : 후원 시스템 최종 패치
This commit is contained in:
parent
27ac11e2b4
commit
4780ff764f
@ -42,6 +42,9 @@ namespace Streamingle
|
||||
[Tooltip("Time to stay after reaching target before deactivating")]
|
||||
public float postArrivalLifetime = 3f;
|
||||
|
||||
[Tooltip("Time spent shrinking out before disappearing (0 = pop instantly)")]
|
||||
public float shrinkDuration = 0.4f;
|
||||
|
||||
// Trajectory state
|
||||
private Vector3 startPosition;
|
||||
private Vector3 targetPosition;
|
||||
@ -64,11 +67,16 @@ namespace Streamingle
|
||||
private float lifetime;
|
||||
private float spawnTime;
|
||||
|
||||
// Despawn (shrink-out)
|
||||
private Vector3 originalScale;
|
||||
private bool isDespawning = false;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
rb = GetComponent<Rigidbody>();
|
||||
audioSource = GetComponent<AudioSource>();
|
||||
colliders = GetComponents<Collider>();
|
||||
originalScale = transform.localScale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -89,7 +97,11 @@ namespace Streamingle
|
||||
this.hasArrived = false;
|
||||
this.hasCollided = false;
|
||||
this.hasPlayedHitFeedback = false;
|
||||
this.isDespawning = false;
|
||||
this.isFlying = true;
|
||||
|
||||
// Restore scale in case this pooled object was shrunk out last time
|
||||
transform.localScale = originalScale;
|
||||
this.currentTime = 0f;
|
||||
this.flightTime = flightDuration;
|
||||
this.startPosition = transform.position;
|
||||
@ -124,7 +136,7 @@ namespace Streamingle
|
||||
// Check lifetime
|
||||
if (lifetime > 0 && Time.time - spawnTime > lifetime)
|
||||
{
|
||||
Deactivate();
|
||||
BeginDespawn();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -195,8 +207,8 @@ namespace Streamingle
|
||||
rb.angularVelocity = rotationAxis * rotationSpeed * Mathf.Deg2Rad;
|
||||
}
|
||||
|
||||
// Schedule deactivation (object falls if no collision)
|
||||
Invoke(nameof(Deactivate), postArrivalLifetime);
|
||||
// Schedule despawn (object falls if no collision, then shrinks out)
|
||||
Invoke(nameof(BeginDespawn), postArrivalLifetime);
|
||||
}
|
||||
|
||||
void OnCollisionEnter(Collision collision)
|
||||
@ -286,13 +298,56 @@ namespace Streamingle
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begin the despawn sequence. Shrinks the object out over shrinkDuration
|
||||
/// before actually deactivating, so it doesn't pop out abruptly.
|
||||
/// </summary>
|
||||
private void BeginDespawn()
|
||||
{
|
||||
if (isDespawning) return;
|
||||
isDespawning = true;
|
||||
isFlying = false;
|
||||
|
||||
// Cancel the scheduled BeginDespawn so it can't fire again mid-shrink.
|
||||
CancelInvoke();
|
||||
|
||||
if (shrinkDuration > 0f && gameObject.activeInHierarchy)
|
||||
{
|
||||
StartCoroutine(ShrinkAndDeactivate());
|
||||
}
|
||||
else
|
||||
{
|
||||
Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
private System.Collections.IEnumerator ShrinkAndDeactivate()
|
||||
{
|
||||
Vector3 from = transform.localScale;
|
||||
float t = 0f;
|
||||
while (t < shrinkDuration)
|
||||
{
|
||||
t += Time.deltaTime;
|
||||
float k = Mathf.Clamp01(t / shrinkDuration);
|
||||
transform.localScale = Vector3.Lerp(from, Vector3.zero, k);
|
||||
yield return null;
|
||||
}
|
||||
transform.localScale = Vector3.zero;
|
||||
Deactivate();
|
||||
}
|
||||
|
||||
private void Deactivate()
|
||||
{
|
||||
CancelInvoke();
|
||||
StopAllCoroutines();
|
||||
isFlying = false;
|
||||
hasArrived = false;
|
||||
hasCollided = false;
|
||||
hasPlayedHitFeedback = false;
|
||||
isDespawning = false;
|
||||
|
||||
// Restore scale so the pooled/recycled object starts at full size next time.
|
||||
transform.localScale = originalScale;
|
||||
|
||||
if (launcher != null && launcher.usePooling)
|
||||
{
|
||||
@ -313,6 +368,7 @@ namespace Streamingle
|
||||
hasArrived = false;
|
||||
hasCollided = false;
|
||||
hasPlayedHitFeedback = false;
|
||||
isDespawning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,8 +234,16 @@ namespace WefLab
|
||||
public string ttsLang = "ko";
|
||||
|
||||
[Header("Debug")]
|
||||
[Tooltip("Log the full raw JSON payload of every received socket event. Use this to inspect real platform donation/chat structures.")]
|
||||
public bool verboseRawLog = true;
|
||||
[Tooltip("Show detailed WefLab logs in the console (raw payloads, every socket event, ping/pong, handshakes, platform-feed keepalives, chat). " +
|
||||
"Off keeps the console clean - only donations, connection status and errors are logged.")]
|
||||
public bool verboseLog = false;
|
||||
|
||||
/// <summary>Console log that only fires when verboseLog (detail logging) is enabled.</summary>
|
||||
private void VLog(string message)
|
||||
{
|
||||
if (verboseLog)
|
||||
UnityEngine.Debug.Log(message);
|
||||
}
|
||||
|
||||
// Queue state (visible in Inspector for debugging)
|
||||
[Header("Queue Status (Read Only)")]
|
||||
@ -641,13 +649,13 @@ namespace WefLab
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Connecting to: {conn.wsUrl}");
|
||||
VLog($"[WefLab] ({conn.Label}) Connecting to: {conn.wsUrl}");
|
||||
|
||||
conn.ws = new WebSocket(conn.wsUrl);
|
||||
|
||||
// Capture conn in the handlers so each message knows which socket it came from
|
||||
conn.ws.OnOpen += (sender, e) =>
|
||||
EnqueueMainThreadAction(() => Debug.Log($"[WefLab] ({conn.Label}) WebSocket connection opened"));
|
||||
EnqueueMainThreadAction(() => VLog($"[WefLab] ({conn.Label}) WebSocket connection opened"));
|
||||
|
||||
conn.ws.OnMessage += (sender, e) =>
|
||||
{
|
||||
@ -666,7 +674,7 @@ namespace WefLab
|
||||
conn.ws.OnClose += (sender, e) =>
|
||||
EnqueueMainThreadAction(() =>
|
||||
{
|
||||
Debug.Log($"[WefLab] ({conn.Label}) WebSocket closed. Code: {e.Code}, Reason: {e.Reason}");
|
||||
VLog($"[WefLab] ({conn.Label}) WebSocket closed. Code: {e.Code}, Reason: {e.Reason}");
|
||||
conn.connected = false;
|
||||
conn.engineSid = "";
|
||||
conn.socketSid = "";
|
||||
@ -752,7 +760,7 @@ namespace WefLab
|
||||
break;
|
||||
|
||||
case "3": // Engine.IO PONG
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Received PONG");
|
||||
VLog($"[WefLab] ({conn.Label}) Received PONG");
|
||||
break;
|
||||
|
||||
case "40": // Socket.IO CONNECT
|
||||
@ -764,7 +772,7 @@ namespace WefLab
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Unknown message type: {messageType} | Data: {data}");
|
||||
VLog($"[WefLab] ({conn.Label}) Unknown message type: {messageType} | Data: {data}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -786,8 +794,8 @@ namespace WefLab
|
||||
|
||||
UpdateAggregateState();
|
||||
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Engine.IO OPEN - SID: {conn.engineSid}, PingInterval: {pingInterval}s");
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Full handshake data: {payload}");
|
||||
VLog($"[WefLab] ({conn.Label}) Engine.IO OPEN - SID: {conn.engineSid}, PingInterval: {pingInterval}s");
|
||||
VLog($"[WefLab] ({conn.Label}) Full handshake data: {payload}");
|
||||
|
||||
// Send Socket.IO CONNECT
|
||||
SendSocketConnect(conn);
|
||||
@ -803,7 +811,7 @@ namespace WefLab
|
||||
/// </summary>
|
||||
private void HandlePing(PlatformConnection conn)
|
||||
{
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Received PING, sending PONG");
|
||||
VLog($"[WefLab] ({conn.Label}) Received PING, sending PONG");
|
||||
SendMessage(conn, "3"); // Send PONG
|
||||
}
|
||||
|
||||
@ -818,8 +826,8 @@ namespace WefLab
|
||||
{
|
||||
var connectData = JsonConvert.DeserializeObject<JObject>(payload);
|
||||
conn.socketSid = connectData["sid"]?.ToString() ?? "";
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Socket.IO CONNECT - SID: {conn.socketSid}");
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Full connect data: {payload}");
|
||||
VLog($"[WefLab] ({conn.Label}) Socket.IO CONNECT - SID: {conn.socketSid}");
|
||||
VLog($"[WefLab] ({conn.Label}) Full connect data: {payload}");
|
||||
}
|
||||
|
||||
conn.connected = true;
|
||||
@ -868,7 +876,7 @@ namespace WefLab
|
||||
};
|
||||
|
||||
string fullMessage = "42" + JsonConvert.SerializeObject(new object[] { "msg", msg });
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Sending PLATFORM feed message (start={start})");
|
||||
VLog($"[WefLab] ({conn.Label}) Sending PLATFORM feed message (start={start})");
|
||||
SendMessage(conn, fullMessage);
|
||||
}
|
||||
|
||||
@ -914,7 +922,7 @@ namespace WefLab
|
||||
// The server also emits bare events like ["pong"] - ignore anything that isn't a "msg" payload
|
||||
if (eventName != "msg")
|
||||
{
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Socket event '{eventName}' (ignored)");
|
||||
VLog($"[WefLab] ({conn.Label}) Socket event '{eventName}' (ignored)");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -923,10 +931,10 @@ namespace WefLab
|
||||
|
||||
var envelope = eventArray[1] as JObject;
|
||||
|
||||
Debug.Log($"[WefLab] ===== EVENT ({conn.Label}) name={eventName} type={envelope?["type"]} =====");
|
||||
VLog($"[WefLab] ===== EVENT ({conn.Label}) name={eventName} type={envelope?["type"]} =====");
|
||||
|
||||
// Verbose: dump the full raw payload so real (non-test) platform structures can be verified
|
||||
if (verboseRawLog && envelope != null)
|
||||
if (verboseLog && envelope != null)
|
||||
Debug.Log($"[WefLab] RAW ({conn.Label}):\n{envelope.ToString(Formatting.Indented)}");
|
||||
|
||||
HandleMessageEnvelope(conn.platform, envelope);
|
||||
@ -966,15 +974,16 @@ namespace WefLab
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.Log($"[WefLab] ({fallbackPlatform}) Ignored envelope type: '{envType}'");
|
||||
VLog($"[WefLab] ({fallbackPlatform}) Ignored envelope type: '{envType}'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a platform's raw donation value to KRW.
|
||||
/// Prefers the server-provided currency.real (already KRW); otherwise applies the
|
||||
/// per-platform conversion derived from weflab's client (comm.donation.currency).
|
||||
/// Unit semantics confirmed by live testing:
|
||||
/// - afreeca/soop/soopg/twitch: value is an item count (balloon/bit), 1 unit = 100 KRW (x100)
|
||||
/// - naver(chzzk)/youtube/cime/extdona: value is already the KRW amount (x1, as-is)
|
||||
/// </summary>
|
||||
private static int ConvertToKrw(string platform, JObject data, out int rawValue)
|
||||
{
|
||||
@ -982,32 +991,16 @@ namespace WefLab
|
||||
if (data["value"] != null)
|
||||
int.TryParse(data["value"].ToString(), out rawValue);
|
||||
|
||||
// 1) Trust server-provided KRW when present (naver/youtube/twitch send this)
|
||||
if (data["currency"] is JObject currency && currency["real"] != null
|
||||
&& int.TryParse(currency["real"].ToString(), out int realKrw))
|
||||
{
|
||||
return realKrw;
|
||||
}
|
||||
|
||||
// 2) Per-platform fallback conversion
|
||||
switch ((platform ?? "").ToLowerInvariant())
|
||||
{
|
||||
case "afreeca":
|
||||
case "soop":
|
||||
case "soopg":
|
||||
return rawValue * 100; // 1 balloon / gem = 100 KRW
|
||||
|
||||
case "twitch":
|
||||
return rawValue / 10; // bits -> KRW (approx; currency.real preferred)
|
||||
|
||||
case "naver": // chzzk cheese
|
||||
case "chzzk":
|
||||
case "youtube": // superchat
|
||||
case "cime":
|
||||
case "extdona":
|
||||
return rawValue / 100; // raw value is in 1/100 KRW units
|
||||
return rawValue * 100; // count (balloon / bit) -> KRW
|
||||
|
||||
default:
|
||||
// naver(chzzk), youtube, cime, extdona: value is already KRW
|
||||
return rawValue;
|
||||
}
|
||||
}
|
||||
@ -1021,19 +1014,23 @@ namespace WefLab
|
||||
return;
|
||||
|
||||
string platform = data["platform"]?.ToString() ?? fallbackPlatform;
|
||||
string subtype = data["subtype"]?.ToString() ?? "";
|
||||
// Real alerts use "subtype"; dashboard test donations use "type" instead.
|
||||
string subtype = data["subtype"]?.ToString();
|
||||
if (string.IsNullOrEmpty(subtype))
|
||||
subtype = data["type"]?.ToString() ?? "";
|
||||
|
||||
int amount = ConvertToKrw(platform, data, out int rawValue);
|
||||
|
||||
// Skip non-monetary alerts (subscribe / membership / follow / emoticon, value = 0, ...)
|
||||
if (NonMonetarySubtypes.Contains(subtype) || amount <= 0)
|
||||
{
|
||||
Debug.Log($"[WefLab] ({platform}) Non-monetary alert ignored (subtype:'{subtype}', value:{rawValue}, krw:{amount})");
|
||||
VLog($"[WefLab] ({platform}) Non-monetary alert ignored (subtype:'{subtype}', value:{rawValue}, krw:{amount})");
|
||||
return;
|
||||
}
|
||||
|
||||
string message = data["msg"]?.ToString() ?? data["message"]?.ToString() ?? "";
|
||||
string donorName = data["name"]?.ToString() ?? data["id"]?.ToString() ?? "Anonymous";
|
||||
// Real alerts use "name"; test donations use "uname".
|
||||
string donorName = data["name"]?.ToString() ?? data["uname"]?.ToString() ?? data["id"]?.ToString() ?? "Anonymous";
|
||||
string donorId = data["id"]?.ToString() ?? "";
|
||||
long timestamp = data["time"]?.Value<long>() ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
|
||||
@ -1092,9 +1089,9 @@ namespace WefLab
|
||||
};
|
||||
|
||||
if (isWarn)
|
||||
Debug.Log($"[WefLab] CHAT WARN ({platform}): {chat.warnType}");
|
||||
VLog($"[WefLab] CHAT WARN ({platform}): {chat.warnType}");
|
||||
else
|
||||
Debug.Log($"[WefLab] CHAT ({platform}): {chat.nickname}: {chat.message}" +
|
||||
VLog($"[WefLab] CHAT ({platform}): {chat.nickname}: {chat.message}" +
|
||||
(chat.emoticons.Count > 0 ? $" [+{chat.emoticons.Count} emoticon]" : ""));
|
||||
|
||||
onChatReceived?.Invoke(chat);
|
||||
@ -1189,7 +1186,7 @@ namespace WefLab
|
||||
// Drop duplicates that arrive on more than one socket within the window
|
||||
if (IsDuplicateDonation(donation))
|
||||
{
|
||||
Debug.Log($"[WefLab] Duplicate donation ignored: {donation.donorName} {donation.amount} ({donation.platform})");
|
||||
VLog($"[WefLab] Duplicate donation ignored: {donation.donorName} {donation.amount} ({donation.platform})");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1207,7 +1204,7 @@ namespace WefLab
|
||||
|
||||
donationQueue.Enqueue(donation);
|
||||
queueCount = donationQueue.Count;
|
||||
Debug.Log($"[WefLab] Donation queued. Queue size: {queueCount}");
|
||||
VLog($"[WefLab] Donation queued. Queue size: {queueCount}");
|
||||
|
||||
// Start queue processor if not running
|
||||
if (!isProcessingQueue)
|
||||
@ -1518,7 +1515,7 @@ namespace WefLab
|
||||
/// </summary>
|
||||
private void SendSocketConnect(PlatformConnection conn)
|
||||
{
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Sending Socket.IO CONNECT (40)");
|
||||
VLog($"[WefLab] ({conn.Label}) Sending Socket.IO CONNECT (40)");
|
||||
SendMessage(conn, "40");
|
||||
}
|
||||
|
||||
@ -1561,7 +1558,7 @@ namespace WefLab
|
||||
string json = JsonConvert.SerializeObject(message);
|
||||
string fullMessage = "42" + json;
|
||||
|
||||
Debug.Log($"[WefLab] ({conn.Label}) Sending JOIN message: {fullMessage}");
|
||||
VLog($"[WefLab] ({conn.Label}) Sending JOIN message: {fullMessage}");
|
||||
SendMessage(conn, fullMessage);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user