-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathRPCProxy4Rep.cpp
More file actions
125 lines (109 loc) · 3.84 KB
/
RPCProxy4Rep.cpp
File metadata and controls
125 lines (109 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Fill out your copyright notice in the Description page of Project Settings.
#include "RPCProxy4Rep.h"
#include "Engine/World.h"
#include "Engine/Engine.h"
#include "Engine/NetConnection.h"
#include "GameFramework/PlayerController.h"
#include "PropertyPortFlags.h"
#include "ObjectMacros.h"
//////////////////////////////////////////////////////////////////////////
URPCProxy4Rep::URPCProxy4Rep()
{
PrimaryComponentTick.bCanEverTick = false;
PrimaryComponentTick.bStartWithTickEnabled = false;
SetIsReplicated(true);
// if (HasAnyFlags(RF_ClassDefaultObject))
// {
// // Auto Bind To PlayerController
// ::RegisterAutoSpawnComponent(APlayerController::StaticClass(), URPCProxy4Rep::StaticClass());
// }
}
class UPackageMap* URPCProxy4Rep::GetPackageMap(APlayerController* PC) { return PC->GetNetConnection()->PackageMap; }
void URPCProxy4Rep::__Internal_Call(UObject* InUserObject, FName InFunctionName, const TArray<uint8>& Buffer)
{
UFunction* Function = InUserObject ? InUserObject->FindFunction(InFunctionName) : nullptr;
bool bExist = Function && Function->HasAnyFunctionFlags(FUNC_Native);
ensure(bExist || GetNetMode() == NM_Client);
if (!bExist || !ensure(Buffer.Num() * 8 <= MaxBitCount))
return;
uint8* Parms = (uint8*)FMemory_Alloca(Function->ParmsSize);
FMemory::Memzero(Parms, Function->ParmsSize);
int32 NumParamsEvaluated = 0;
for (TFieldIterator<UProperty> It(Function); It && It->HasAnyPropertyFlags(CPF_Parm); ++It, ++NumParamsEvaluated)
{
UProperty* LocalProp = *It;
#if WITH_EDITOR
if (!LocalProp || It->HasAnyPropertyFlags(CPF_ReturnParm))
{
int32 Count = NumParamsEvaluated;
for (TFieldIterator<UProperty> It2(Function); Count > 0 && It2->HasAnyPropertyFlags(CPF_Parm);
++It2, --Count)
{ It2->DestroyValue_InContainer(Parms); }
return;
}
#endif
if (!LocalProp->HasAnyPropertyFlags(CPF_ZeroConstructor))
{
LocalProp->InitializeValue_InContainer(Parms);
}
}
bool bSucc = true;
do
{
TFieldIterator<UProperty> It(Function);
FNetBitReader Reader{GetPackageMap(Cast<APlayerController>(GetOwner())), const_cast<uint8*>(Buffer.GetData()),
Buffer.Num() * 8};
for (; It && It->HasAnyPropertyFlags(CPF_Parm); ++It)
{
if (It->HasAnyPropertyFlags(CPF_ReturnParm))
{
bSucc = false;
break;
}
UProperty* PropertyParam = *It;
PropertyParam->SerializeItem(Reader, PropertyParam->ContainerPtrToValuePtr<uint8>(Parms));
if (!ensure(!Reader.GetError()))
{
bSucc = false;
break;
}
}
} while (0);
if (bSucc)
InUserObject->ProcessEvent(Function, Parms);
for (TFieldIterator<UProperty> It(Function); It && It->HasAnyPropertyFlags(CPF_Parm); ++It)
{ It->DestroyValue_InContainer(Parms); }
}
void URPCProxy4Rep::RPC_Reuqest_Implementation(UObject* Object, const FName& FuncName, const TArray<uint8>& Buffer)
{
__Internal_Call(Object, FuncName, Buffer);
}
bool URPCProxy4Rep::RPC_Reuqest_Validate(UObject* Object, const FName& FuncName, const TArray<uint8>& Buffer)
{
return ensure(IsValid(Object) && Object->FindFunction(FuncName));
}
void URPCProxy4Rep::RPC_Notify_Implementation(UObject* Object, const FName& FuncName, const TArray<uint8>& Buffer)
{
__Internal_Call(Object, FuncName, Buffer);
}
void URPCProxy4Rep::__Internal_CallRemote(class APlayerController* PC, UObject* InUserObject,
const FName& InFunctionName, const TArray<uint8>& Buffer)
{
if (auto World = GEngine->GetWorldFromContextObject(InUserObject, EGetWorldErrorMode::LogAndReturnNull))
{
bool bClient = World->GetNetMode() != NM_DedicatedServer;
if (!PC && bClient)
PC = World->GetFirstPlayerController();
if (ensure(PC))
{
if (auto Comp = PC->FindComponentByClass<URPCProxy4Rep>())
{
if (bClient)
Comp->RPC_Reuqest(InUserObject, InFunctionName, Buffer);
else
Comp->RPC_Notify(InUserObject, InFunctionName, Buffer);
}
}
}
}
int64 URPCProxy4Rep::MaxBitCount = 1024 * 8;