feat(upserver): 接入认证与KV存档并完成限定钓鱼闭环

This commit is contained in:
Liubing\LB
2026-09-28 18:14:01 +08:00
parent f40a816cc4
commit 0eb43b2b40
129 changed files with 11612 additions and 573 deletions

View File

@@ -6,6 +6,7 @@ using GameCore;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UniRx;
using UnityEngine;
@@ -23,6 +24,52 @@ public class ShowHandEvent
[DefaultExecutionOrder(10000)]
public partial class FishingBehaviorB : MonoBehaviour
{
#if UNITY_EDITOR && !SERVICE_HOST
game.PlayerDataStorage.PlayerKVGameplayLoop.FishingAction kvFishingAction;
bool KVFishingCurrent()
{
if(!game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled) return true;
return this!=null && isActiveAndEnabled && game.PlayerDataStorage.PlayerKVGameplayLoop.FishingCurrent(kvFishingAction);
}
void CancelKVFishing(string reason) => game.PlayerDataStorage.PlayerKVGameplayLoop.CancelFishing(kvFishingAction,reason);
void TrackKVCastTween(Tween tween)
{
if(!game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled) return;
var action=kvFishingAction;
bool completed=false;
tween.onComplete+=()=>completed=true;
tween.onKill+=()=> { if(!completed) game.PlayerDataStorage.PlayerKVGameplayLoop.CancelFishing(action,"cast tween killed"); };
}
async Task ConsumeBaitOnKVAsync()
{
try
{
if(!KVFishingCurrent()) return;
if(!game.PlayerDataStorage.PlayerKVGameplayLoop.ClaimFishingConsumption(kvFishingAction)) return;
if(fishingData.fishItem==null || !fishingData.IsGeneralFish() || fishingData.IsFree || fishingData.IsRetry ||
fishingData.IsDuel || fishingData.IsPackItemFish() || fishingData.curFishData==null)
throw game.PlayerDataStorage.PlayerKVGameplayLoop.Stop("Only one ordinary paid fishing action is permitted. fishItem.ID="+(fishingData.fishItem==null?"null":fishingData.fishItem.ID.ToString())+", fishItem.SubType="+(fishingData.fishItem==null?"null":fishingData.fishItem.SubType.ToString())+", curFishData.ID="+(fishingData.curFishData==null?"null":fishingData.curFishData.ID.ToString())+", IsFree="+fishingData.IsFree+", IsRetry="+fishingData.IsRetry+", IsDuel="+fishingData.IsDuel);
if(Application.internetReachability==NetworkReachability.NotReachable)
throw game.PlayerDataStorage.PlayerKVGameplayLoop.Stop("Fishing stopped before consumption: offline.");
if(_tables.TbFishingEvent.DataList.Any(e=>e.ConditionList.Any(c=>c.Condition==ConditionType.ConsumeEnergy)))
throw game.PlayerDataStorage.PlayerKVGameplayLoop.Stop("ConsumeEnergy activity activation requires separate review.");
var player=GContext.container.Resolve<PlayerData>();
int mag=player.magnification;
if(mag<0 || mag>=_tables.TbEnergyDef.DataList.Count)
throw game.PlayerDataStorage.PlayerKVGameplayLoop.Stop("Invalid fishing magnification.");
int fish=fishingData.curFishData.ID, rod=fishingData.RodId, map=player.lastMapId;
int cost=_tables.TbEnergyDef.DataList[mag].Mag;
game.PlayerDataStorage.PlayerKVGameplayLoop.PrepareFishingReward(kvFishingAction,fishingData);
await player.ConsumeEnergyForKVLoopAsync(cost,kvFishingAction);
if(!KVFishingCurrent()) return;
if(fishingData.curFishData==null || fishingData.curFishData.ID!=fish || fishingData.RodId!=rod ||
player.lastMapId!=map || (int)player.magnification!=mag || fishingData.IsFree || fishingData.IsRetry || fishingData.IsDuel)
throw game.PlayerDataStorage.PlayerKVGameplayLoop.Stop("Fishing context changed during confirmation.");
game.PlayerDataStorage.PlayerKVGameplayLoop.ContinueFishing(kvFishingAction,WaitForFishBiteED);
}
catch(Exception e) { game.PlayerDataStorage.PlayerKVGameplayLoop.Fault(e.Message); }
}
#endif
Tables _tables;
[Header("RELATED OBJECT SETTINGS")]
[SerializeField]
@@ -213,7 +260,13 @@ public partial class FishingBehaviorB : MonoBehaviour
{
Addressables.ReleaseInstance(handAB);
}
handAB = await Addressables.InstantiateAsync(gloveData.Fbx, transform).Task;
var loadedHand = await Addressables.InstantiateAsync(gloveData.Fbx, transform).Task;
if (this == null)
{
if (loadedHand != null) Addressables.ReleaseInstance(loadedHand);
return;
}
handAB = loadedHand;
if (handAB != null)
{
HandController = handAB.GetComponent<HandController>();
@@ -225,7 +278,13 @@ public partial class FishingBehaviorB : MonoBehaviour
}
async void LoadBait()
{
baitAB = await Addressables.InstantiateAsync("BaitRoot", _bait.transform).Task;
var loadedBait = await Addressables.InstantiateAsync("BaitRoot", _bait.transform).Task;
if (this == null)
{
if (loadedBait != null) Addressables.ReleaseInstance(loadedBait);
return;
}
baitAB = loadedBait;
baitAB.transform.localPosition = Vector3.zero;
baitAB.transform.localRotation = Quaternion.identity;
baitAB.transform.localScale = Vector3.one;
@@ -421,10 +480,20 @@ public partial class FishingBehaviorB : MonoBehaviour
float FishingScale = fishRodSkinData.FishingScale;
var goPrefab = await Addressables.LoadAssetAsync<GameObject>(path).Task;
if (this == null)
{
if (goPrefab != null) Addressables.Release(goPrefab);
return;
}
if (goPrefab == null)
{
Debug.LogError("Load Rod Elemental as Default Rod");
goPrefab = await Addressables.LoadAssetAsync<GameObject>("Rod_elemental").Task;
if (this == null)
{
if (goPrefab != null) Addressables.Release(goPrefab);
return;
}
}
_bait.transform.SetParent(transform);
if (goPrefab != null)
@@ -690,9 +759,25 @@ public partial class FishingBehaviorB : MonoBehaviour
//开始抛鱼线
public async void CastLineBehavior()
{
#if UNITY_EDITOR && !SERVICE_HOST
if(game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled)
{
try
{
var action=game.PlayerDataStorage.PlayerKVGameplayLoop.BeginFishing(this);
if(action==null) return;
kvFishingAction=action;
if(!KVFishingCurrent()) return;
}
catch(Exception e) { game.PlayerDataStorage.PlayerKVGameplayLoop.Fault(e.Message); return; }
}
#endif
//计算主画布分辨率下的宽高和屏幕的宽高的比列:
fishingData.mainCamera.DOLocalRotateQuaternion(Quaternion.identity, 0.1f);
await Awaiters.NextFrame;
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) return;
#endif
CastBait();
//播放抛竿动画
@@ -703,12 +788,18 @@ public partial class FishingBehaviorB : MonoBehaviour
rodHandleAni.SetBool("_idle", false);
rodHandleAni.SetTrigger("_drawing");
await Awaiters.Seconds(fishingBehaviorConf.audioDelay);
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) return;
#endif
GContext.Publish(new EventFishingSound(SoundType.ThrowingAudio));
GContext.Publish(new VibrationData(1));
}
private void ConsumeBait()
{
#if UNITY_EDITOR && !SERVICE_HOST
if(game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled) { _=ConsumeBaitOnKVAsync(); return; }
#endif
if (fishingData.IsFree)
{
WaitForFishBiteED();
@@ -910,6 +1001,9 @@ public partial class FishingBehaviorB : MonoBehaviour
}
public void BaitMove()
{
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) return;
#endif
flyEndPosTrue = _bait.transform.position;
GContext.Publish(new EventFishingSound(SoundType.audio_fishing_throwing_baitintowater));
@@ -920,9 +1014,12 @@ public partial class FishingBehaviorB : MonoBehaviour
var fishEffect = _effectDic["fx_fishing_splashloopwaiting"];
float z = WaitingZ();
float timer = Mathf.Lerp(fishingBehaviorConf.waitingLineDrawMinTime, fishingBehaviorConf.waitingLineDrawMaxTime, Random.value);
_bait.transform.DOLocalMoveZ(z, timer).OnUpdate(
var waitingTween=_bait.transform.DOLocalMoveZ(z, timer).OnUpdate(
(() =>
{
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) return;
#endif
flyEndPosTrue = _bait.transform.position;
if (fishEffect)
{
@@ -931,6 +1028,9 @@ public partial class FishingBehaviorB : MonoBehaviour
fishEffect.transform.position = vector;
}
})); ;
#if UNITY_EDITOR && !SERVICE_HOST
TrackKVCastTween(waitingTween);
#endif
StartCoroutine(WaitForFishBite(timer));
}
IEnumerator PlayWaitingFx()
@@ -953,6 +1053,9 @@ public partial class FishingBehaviorB : MonoBehaviour
}
private IEnumerator WaitForFishBite(float timer)
{
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) yield break;
#endif
EventFishingSound eventFishingSound1 = new EventFishingSound(SoundType.audio_fishing_waiting);
EventFishingSound eventFishingSound2 = new EventFishingSound(SoundType.ReelingAudio, loop: true);
@@ -962,6 +1065,9 @@ public partial class FishingBehaviorB : MonoBehaviour
timer += Mathf.Lerp(fishingBehaviorConf.waitingMinTime, fishingBehaviorConf.waitingMaxTime, Random.value) * (1 - EnhancedWaitingTime);
yield return new WaitForSeconds(timer);
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) yield break;
#endif
if (eventFishingSound2.Sound != null)
{
@@ -1085,18 +1191,27 @@ public partial class FishingBehaviorB : MonoBehaviour
}
private async void CastBait()
{
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) return;
#endif
InitEffect();
if (fishingBehaviorConf.fishFreeControlTime > 0f)
{
await new WaitForSeconds(fishingBehaviorConf.fishFreeControlTime);
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) return;
#endif
_isCastLine = true;
_bait.transform.SetParent(transform);
_bait.transform.DOMoveX(0, fishingBehaviorConf.flyToWaterTime);
_bait.transform.DOMoveZ(fishingBehaviorConf.flyDistance, fishingBehaviorConf.flyToWaterTime).SetEase(fishingBehaviorConf.flyForwardCurve);
var castX=_bait.transform.DOMoveX(0, fishingBehaviorConf.flyToWaterTime);
var castZ=_bait.transform.DOMoveZ(fishingBehaviorConf.flyDistance, fishingBehaviorConf.flyToWaterTime).SetEase(fishingBehaviorConf.flyForwardCurve);
_cameraAnimator.SetTrigger("_waiting");
_bait.transform.DOMoveY(_waterHeight, fishingBehaviorConf.flyToWaterTime)
var castY=_bait.transform.DOMoveY(_waterHeight, fishingBehaviorConf.flyToWaterTime)
.SetEase(fishingBehaviorConf.flyDownCurve).OnComplete((() =>
{
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) return;
#endif
fishingRodAnimator.SetTrigger("_waiting");
GContext.Publish(ERightState.Waiting);
LoadEffect("fx_fishing_splashinto");
@@ -1106,16 +1221,25 @@ public partial class FishingBehaviorB : MonoBehaviour
BaitMove();
_bait.SetActive(false);
}));
#if UNITY_EDITOR && !SERVICE_HOST
TrackKVCastTween(castX); TrackKVCastTween(castZ); TrackKVCastTween(castY);
#endif
AddLinePos();
}
else
{
await new WaitForSeconds(1.15f);
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) return;
#endif
//当前动画_fishingRodAnimator播放时间
float time = fishingRodAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime;
_isCastLine = true;
_cameraAnimator.SetTrigger("_waiting");
await new WaitForSeconds(time);
#if UNITY_EDITOR && !SERVICE_HOST
if(!KVFishingCurrent()) return;
#endif
_bait.transform.SetParent(transform);
_bait.SetActive(false);
//鱼漂位置
@@ -1259,7 +1383,7 @@ public partial class FishingBehaviorB : MonoBehaviour
}
void SetIKTarget(Transform target)
{
if (RodBehaviour.cCDIK)
if (RodBehaviour != null && RodBehaviour.cCDIK)
{
RodBehaviour.cCDIK.solver.target = target;
}
@@ -1896,6 +2020,9 @@ public partial class FishingBehaviorB : MonoBehaviour
_cameraAnimator.SetBool("_reeling", false);
fishingRodAnimator.SetBool("_pulling", false);
CameraPullingEnd();
#if UNITY_EDITOR && !SERVICE_HOST
if(game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled && (!KVFishingCurrent() || !game.PlayerDataStorage.PlayerKVGameplayLoop.RewardCanAdvance)) yield break;
#endif
fishingData.IsCaughtFish = true;
PlayCollectingEffect();
if (fx_fishing_splashwaveloop != null)
@@ -2308,6 +2435,9 @@ public partial class FishingBehaviorB : MonoBehaviour
private void OnDisable()
{
#if UNITY_EDITOR && !SERVICE_HOST
CancelKVFishing("disabled");
#endif
CloseAllEffect();
}
public void CloseAllEffect()
@@ -2331,6 +2461,9 @@ public partial class FishingBehaviorB : MonoBehaviour
}
private void OnDestroy()
{
#if UNITY_EDITOR && !SERVICE_HOST
CancelKVFishing("destroyed");
#endif
disposables?.Dispose();
disposables = null;
foreach (var o in _effectDic)