-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKick.cpp
More file actions
135 lines (107 loc) · 3.75 KB
/
Kick.cpp
File metadata and controls
135 lines (107 loc) · 3.75 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
126
127
128
129
130
131
132
133
134
135
#include <common/Common.hpp>
#include <dwc/dwc_main.h>
#include <dwc/dwc_match.h>
#include <nw4r/ut/Lock.hpp>
#include <platform/string.h>
#include <wiimmfi/Kick.hpp>
namespace Wiimmfi {
namespace Kick {
u32 sAidsToBeKicked = 0;
bool sMustEndRace = false;
void ScheduleForAID(int aid) {
DEBUG_REPORT("[WIIMMFI_KICK] Scheduled kick for aid %d\n", aid)
sAidsToBeKicked |= (1 << aid);
}
void ScheduleForAIDs(u32 aids) {
DEBUG_REPORT("[WIIMMFI_KICK] Scheduled kick for aids %08X\n", aids)
sAidsToBeKicked |= aids;
}
void ScheduleForEveryone() {
DEBUG_REPORT("[WIIMMFI_KICK] Scheduled kick for all aids\n")
sAidsToBeKicked = 0xFFFFFFFF;
}
void CalcKick() {
// If the aid bitfield is empty, bail
if (!sAidsToBeKicked)
return;
// Lock interrupts
nw4r::ut::AutoInterruptLock lock;
DEBUG_REPORT("[WIIMMFI_KICK] Running kick task with aids %08X\n", sAidsToBeKicked)
// If the bitfield is full, close all connections immediately
if (sAidsToBeKicked == 0xFFFFFFFF)
DWC_CloseAllConnectionsHard();
// Otherwise kick each aid separately
else {
for (int i = 0; i < 12; i++) {
if (sAidsToBeKicked >> i & 1)
DWC_CloseConnectionHard(i);
}
}
// Reset the bitfield
sAidsToBeKicked = 0;
}
int ParseKickMessage(GPConnection conn, char* data) {
// Ignore kick commands if we don't have the necessary structures
if (!stpMatchCnt || stpMatchCnt->nodeInfoList.nodeCount > 1)
return GP_ERROR_NONE;
// If the kick command isn't found, bail
char* kickCmd = strstr(data, KICK_MSG);
if (!kickCmd)
return GP_ERROR_NONE;
// Obtain the kick type
strshift(kickCmd, KICK_MSG);
u32 kickType = strtoul(kickCmd, nullptr, 10);
DEBUG_REPORT("[WIIMMFI_KICK] Received kick type ", kickType)
// Act based on the kick type
switch (kickType) {
// Use CloseConnectionHard to kick everyone (HOST ONLY)
case EVERYONE:
DEBUG_REPORT("EVERYONE\n")
if (!DWC_IsServerMyself()) {
DEBUG_REPORT("[WIIMMFI_KICK] But ignored (not host).\n")
break;
}
ScheduleForEveryone();
break;
// Pretend to cause a network error and kick ourselves
case SELF:
DEBUG_REPORT("SELF\n")
DWCi_HandleGPError(GP_ERROR_NETWORK);
return GP_ERROR_MEMORY;
// Force end the race
case END_RACE:
DEBUG_REPORT("END_RACE\n")
sMustEndRace = true;
break;
// Kick a specific player (HOST ONLY)
case SPECIFIC_PLAYER:
DEBUG_REPORT("PLAYER\n")
if (!DWC_IsServerMyself()) {
DEBUG_REPORT("[WIIMMFI_KICK] But ignored (not host).\n")
break;
}
// Get the kickpid parameter, if not found bail
char* pidKickParam = strstr(kickCmd, KICK_MSG_PARAM_PID);
if (!pidKickParam) {
DEBUG_REPORT("[WIIMMFI_KICK] But ignored (no PID specified).\n")
break;
}
// Shift the string and read the pid to an integer
strshift(pidKickParam, KICK_MSG_PARAM_PID);
u32 pidToKick = strtoul(pidKickParam, nullptr, 10);
// Get the node info
// If it exists, kick the corresponding aid
DWCNodeInfo* node = DWCi_NodeInfoList_GetNodeInfoForProfileId(pidToKick);
if (!node) {
DEBUG_REPORT("[WIIMMFI_KICK] But ignored (AID not found).\n")
break;
}
ScheduleForAID(node->aid);
break;
default:
DEBUG_REPORT("UNKNOWN (%d)\n", kickType);
}
return GP_ERROR_NONE;
}
} // namespace Kick
} // namespace Wiimmfi