mirror of
https://github.com/minetest/minetest.git
synced 2024-11-05 07:13:46 +01:00
Client::Interact: Use InteractAction enum instead of numeric constants
This replaces the magic numbers used as interaction modes both client-side and server-side, primarily for the sake of ease-of-readability.
This commit is contained in:
parent
e462a9a5ef
commit
e788ee283f
@ -908,7 +908,7 @@ void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *
|
|||||||
*pkt << fov << wanted_range;
|
*pkt << fov << wanted_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::interact(u8 action, const PointedThing& pointed)
|
void Client::interact(InteractAction action, const PointedThing& pointed)
|
||||||
{
|
{
|
||||||
if(m_state != LC_Ready) {
|
if(m_state != LC_Ready) {
|
||||||
errorstream << "Client::interact() "
|
errorstream << "Client::interact() "
|
||||||
@ -928,18 +928,11 @@ void Client::interact(u8 action, const PointedThing& pointed)
|
|||||||
[5] u32 length of the next item (plen)
|
[5] u32 length of the next item (plen)
|
||||||
[9] serialized PointedThing
|
[9] serialized PointedThing
|
||||||
[9 + plen] player position information
|
[9 + plen] player position information
|
||||||
actions:
|
|
||||||
0: start digging (from undersurface) or use
|
|
||||||
1: stop digging (all parameters ignored)
|
|
||||||
2: digging completed
|
|
||||||
3: place block or item (to abovesurface)
|
|
||||||
4: use item
|
|
||||||
5: perform secondary action of item
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NetworkPacket pkt(TOSERVER_INTERACT, 1 + 2 + 0);
|
NetworkPacket pkt(TOSERVER_INTERACT, 1 + 2 + 0);
|
||||||
|
|
||||||
pkt << action;
|
pkt << (u8)action;
|
||||||
pkt << myplayer->getWieldIndex();
|
pkt << myplayer->getWieldIndex();
|
||||||
|
|
||||||
std::ostringstream tmp_os(std::ios::binary);
|
std::ostringstream tmp_os(std::ios::binary);
|
||||||
@ -1203,7 +1196,7 @@ void Client::clearOutChatQueue()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Client::sendChangePassword(const std::string &oldpassword,
|
void Client::sendChangePassword(const std::string &oldpassword,
|
||||||
const std::string &newpassword)
|
const std::string &newpassword)
|
||||||
{
|
{
|
||||||
LocalPlayer *player = m_env.getLocalPlayer();
|
LocalPlayer *player = m_env.getLocalPlayer();
|
||||||
if (player == NULL)
|
if (player == NULL)
|
||||||
|
@ -232,7 +232,7 @@ public:
|
|||||||
|
|
||||||
void Send(NetworkPacket* pkt);
|
void Send(NetworkPacket* pkt);
|
||||||
|
|
||||||
void interact(u8 action, const PointedThing& pointed);
|
void interact(InteractAction action, const PointedThing &pointed);
|
||||||
|
|
||||||
void sendNodemetaFields(v3s16 p, const std::string &formname,
|
void sendNodemetaFields(v3s16 p, const std::string &formname,
|
||||||
const StringMap &fields);
|
const StringMap &fields);
|
||||||
|
@ -2962,7 +2962,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
|
|||||||
shootline = core::line3d<f32>(player_eye_position,
|
shootline = core::line3d<f32>(player_eye_position,
|
||||||
player_eye_position + camera_direction * BS * d);
|
player_eye_position + camera_direction * BS * d);
|
||||||
} else {
|
} else {
|
||||||
// prevent player pointing anything in front-view
|
// prevent player pointing anything in front-view
|
||||||
shootline = core::line3d<f32>(camera_position, camera_position);
|
shootline = core::line3d<f32>(camera_position, camera_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3002,7 +3002,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
|
|||||||
if (runData.digging) {
|
if (runData.digging) {
|
||||||
if (input->getLeftReleased()) {
|
if (input->getLeftReleased()) {
|
||||||
infostream << "Left button released"
|
infostream << "Left button released"
|
||||||
<< " (stopped digging)" << std::endl;
|
<< " (stopped digging)" << std::endl;
|
||||||
runData.digging = false;
|
runData.digging = false;
|
||||||
} else if (pointed != runData.pointed_old) {
|
} else if (pointed != runData.pointed_old) {
|
||||||
if (pointed.type == POINTEDTHING_NODE
|
if (pointed.type == POINTEDTHING_NODE
|
||||||
@ -3013,14 +3013,14 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
|
|||||||
// Don't reset.
|
// Don't reset.
|
||||||
} else {
|
} else {
|
||||||
infostream << "Pointing away from node"
|
infostream << "Pointing away from node"
|
||||||
<< " (stopped digging)" << std::endl;
|
<< " (stopped digging)" << std::endl;
|
||||||
runData.digging = false;
|
runData.digging = false;
|
||||||
hud->updateSelectionMesh(camera_offset);
|
hud->updateSelectionMesh(camera_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!runData.digging) {
|
if (!runData.digging) {
|
||||||
client->interact(1, runData.pointed_old);
|
client->interact(INTERACT_STOP_DIGGING, runData.pointed_old);
|
||||||
client->setCrack(-1, v3s16(0, 0, 0));
|
client->setCrack(-1, v3s16(0, 0, 0));
|
||||||
runData.dig_time = 0.0;
|
runData.dig_time = 0.0;
|
||||||
}
|
}
|
||||||
@ -3048,7 +3048,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
|
|||||||
if (selected_def.usable && input->getLeftState()) {
|
if (selected_def.usable && input->getLeftState()) {
|
||||||
if (input->getLeftClicked() && (!client->moddingEnabled()
|
if (input->getLeftClicked() && (!client->moddingEnabled()
|
||||||
|| !client->getScript()->on_item_use(selected_item, pointed)))
|
|| !client->getScript()->on_item_use(selected_item, pointed)))
|
||||||
client->interact(4, pointed);
|
client->interact(INTERACT_USE, pointed);
|
||||||
} else if (pointed.type == POINTEDTHING_NODE) {
|
} else if (pointed.type == POINTEDTHING_NODE) {
|
||||||
handlePointingAtNode(pointed, selected_item, hand_item, dtime);
|
handlePointingAtNode(pointed, selected_item, hand_item, dtime);
|
||||||
} else if (pointed.type == POINTEDTHING_OBJECT) {
|
} else if (pointed.type == POINTEDTHING_OBJECT) {
|
||||||
@ -3169,7 +3169,7 @@ void Game::handlePointingAtNothing(const ItemStack &playerItem)
|
|||||||
infostream << "Right Clicked in Air" << std::endl;
|
infostream << "Right Clicked in Air" << std::endl;
|
||||||
PointedThing fauxPointed;
|
PointedThing fauxPointed;
|
||||||
fauxPointed.type = POINTEDTHING_NOTHING;
|
fauxPointed.type = POINTEDTHING_NOTHING;
|
||||||
client->interact(5, fauxPointed);
|
client->interact(INTERACT_ACTIVATE, fauxPointed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3216,7 +3216,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
|
|||||||
&& !isKeyDown(KeyType::SNEAK)) {
|
&& !isKeyDown(KeyType::SNEAK)) {
|
||||||
// Report right click to server
|
// Report right click to server
|
||||||
if (nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
|
if (nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
|
||||||
client->interact(3, pointed);
|
client->interact(INTERACT_PLACE, pointed);
|
||||||
}
|
}
|
||||||
|
|
||||||
infostream << "Launching custom inventory view" << std::endl;
|
infostream << "Launching custom inventory view" << std::endl;
|
||||||
@ -3246,7 +3246,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
|
|||||||
|
|
||||||
if (placed) {
|
if (placed) {
|
||||||
// Report to server
|
// Report to server
|
||||||
client->interact(3, pointed);
|
client->interact(INTERACT_PLACE, pointed);
|
||||||
// Read the sound
|
// Read the sound
|
||||||
soundmaker->m_player_rightpunch_sound =
|
soundmaker->m_player_rightpunch_sound =
|
||||||
def.sound_place;
|
def.sound_place;
|
||||||
@ -3259,7 +3259,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
|
|||||||
|
|
||||||
if (def.node_placement_prediction.empty() ||
|
if (def.node_placement_prediction.empty() ||
|
||||||
nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
|
nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
|
||||||
client->interact(3, pointed); // Report to server
|
client->interact(INTERACT_PLACE, pointed); // Report to server
|
||||||
} else {
|
} else {
|
||||||
soundmaker->m_player_rightpunch_sound =
|
soundmaker->m_player_rightpunch_sound =
|
||||||
def.sound_place_failed;
|
def.sound_place_failed;
|
||||||
@ -3462,11 +3462,11 @@ void Game::handlePointingAtObject(const PointedThing &pointed,
|
|||||||
runData.time_from_last_punch = 0;
|
runData.time_from_last_punch = 0;
|
||||||
|
|
||||||
if (!disable_send)
|
if (!disable_send)
|
||||||
client->interact(0, pointed);
|
client->interact(INTERACT_START_DIGGING, pointed);
|
||||||
}
|
}
|
||||||
} else if (input->getRightClicked()) {
|
} else if (input->getRightClicked()) {
|
||||||
infostream << "Right-clicked object" << std::endl;
|
infostream << "Right-clicked object" << std::endl;
|
||||||
client->interact(3, pointed); // place
|
client->interact(INTERACT_PLACE, pointed); // place
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3509,7 +3509,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
|||||||
runData.dig_instantly = runData.dig_time_complete == 0;
|
runData.dig_instantly = runData.dig_time_complete == 0;
|
||||||
if (client->moddingEnabled() && client->getScript()->on_punchnode(nodepos, n))
|
if (client->moddingEnabled() && client->getScript()->on_punchnode(nodepos, n))
|
||||||
return;
|
return;
|
||||||
client->interact(0, pointed);
|
client->interact(INTERACT_START_DIGGING, pointed);
|
||||||
runData.digging = true;
|
runData.digging = true;
|
||||||
runData.ldown_for_dig = true;
|
runData.ldown_for_dig = true;
|
||||||
}
|
}
|
||||||
@ -3568,7 +3568,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
|||||||
MapNode wasnode = map.getNodeNoEx(nodepos, &is_valid_position);
|
MapNode wasnode = map.getNodeNoEx(nodepos, &is_valid_position);
|
||||||
if (is_valid_position) {
|
if (is_valid_position) {
|
||||||
if (client->moddingEnabled() &&
|
if (client->moddingEnabled() &&
|
||||||
client->getScript()->on_dignode(nodepos, wasnode)) {
|
client->getScript()->on_dignode(nodepos, wasnode)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3584,7 +3584,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
|||||||
// implicit else: no prediction
|
// implicit else: no prediction
|
||||||
}
|
}
|
||||||
|
|
||||||
client->interact(2, pointed);
|
client->interact(INTERACT_DIGGING_COMPLETED, pointed);
|
||||||
|
|
||||||
if (m_cache_enable_particles) {
|
if (m_cache_enable_particles) {
|
||||||
const ContentFeatures &features =
|
const ContentFeatures &features =
|
||||||
|
@ -954,10 +954,20 @@ enum CSMRestrictionFlags : u64 {
|
|||||||
// When those are complete, this should return to only being a restriction on the
|
// When those are complete, this should return to only being a restriction on the
|
||||||
// loading of client mods.
|
// loading of client mods.
|
||||||
CSM_RF_LOAD_CLIENT_MODS = 0x00000001, // Don't load client-provided mods or 'builtin'
|
CSM_RF_LOAD_CLIENT_MODS = 0x00000001, // Don't load client-provided mods or 'builtin'
|
||||||
CSM_RF_CHAT_MESSAGES = 0x00000002, // Disable chat message sending from CSM
|
CSM_RF_CHAT_MESSAGES = 0x00000002, // Disable chat message sending from CSM
|
||||||
CSM_RF_READ_ITEMDEFS = 0x00000004, // Disable itemdef lookups
|
CSM_RF_READ_ITEMDEFS = 0x00000004, // Disable itemdef lookups
|
||||||
CSM_RF_READ_NODEDEFS = 0x00000008, // Disable nodedef lookups
|
CSM_RF_READ_NODEDEFS = 0x00000008, // Disable nodedef lookups
|
||||||
CSM_RF_LOOKUP_NODES = 0x00000010, // Limit node lookups
|
CSM_RF_LOOKUP_NODES = 0x00000010, // Limit node lookups
|
||||||
CSM_RF_READ_PLAYERINFO = 0x00000020, // Disable player info lookups
|
CSM_RF_READ_PLAYERINFO = 0x00000020, // Disable player info lookups
|
||||||
CSM_RF_ALL = 0xFFFFFFFF,
|
CSM_RF_ALL = 0xFFFFFFFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum InteractAction : u8
|
||||||
|
{
|
||||||
|
INTERACT_START_DIGGING, // 0: start digging (from undersurface) or use
|
||||||
|
INTERACT_STOP_DIGGING, // 1: stop digging (all parameters ignored)
|
||||||
|
INTERACT_DIGGING_COMPLETED, // 2: digging completed
|
||||||
|
INTERACT_PLACE, // 3: place block or item (to abovesurface)
|
||||||
|
INTERACT_USE, // 4: use item
|
||||||
|
INTERACT_ACTIVATE // 5: rightclick air ("activate")
|
||||||
|
};
|
||||||
|
@ -974,7 +974,7 @@ bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::handleCommand_Interact(NetworkPacket* pkt)
|
void Server::handleCommand_Interact(NetworkPacket *pkt)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
[0] u16 command
|
[0] u16 command
|
||||||
@ -983,18 +983,14 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
|
|||||||
[5] u32 length of the next item (plen)
|
[5] u32 length of the next item (plen)
|
||||||
[9] serialized PointedThing
|
[9] serialized PointedThing
|
||||||
[9 + plen] player position information
|
[9 + plen] player position information
|
||||||
actions:
|
|
||||||
0: start digging (from undersurface) or use
|
|
||||||
1: stop digging (all parameters ignored)
|
|
||||||
2: digging completed
|
|
||||||
3: place block or item (to abovesurface)
|
|
||||||
4: use item
|
|
||||||
5: rightclick air ("activate")
|
|
||||||
*/
|
*/
|
||||||
u8 action;
|
|
||||||
|
InteractAction action;
|
||||||
u16 item_i;
|
u16 item_i;
|
||||||
*pkt >> action;
|
|
||||||
|
*pkt >> (u8 &)action;
|
||||||
*pkt >> item_i;
|
*pkt >> item_i;
|
||||||
|
|
||||||
std::istringstream tmp_is(pkt->readLongString(), std::ios::binary);
|
std::istringstream tmp_is(pkt->readLongString(), std::ios::binary);
|
||||||
PointedThing pointed;
|
PointedThing pointed;
|
||||||
pointed.deSerialize(tmp_is);
|
pointed.deSerialize(tmp_is);
|
||||||
@ -1073,18 +1069,18 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
|
|||||||
Make sure the player is allowed to do it
|
Make sure the player is allowed to do it
|
||||||
*/
|
*/
|
||||||
if (!checkPriv(player->getName(), "interact")) {
|
if (!checkPriv(player->getName(), "interact")) {
|
||||||
actionstream<<player->getName()<<" attempted to interact with "
|
actionstream << player->getName() << " attempted to interact with " <<
|
||||||
<<pointed.dump()<<" without 'interact' privilege"
|
pointed.dump() << " without 'interact' privilege" << std::endl;
|
||||||
<<std::endl;
|
|
||||||
// Re-send block to revert change on client-side
|
// Re-send block to revert change on client-side
|
||||||
RemoteClient *client = getClient(pkt->getPeerId());
|
RemoteClient *client = getClient(pkt->getPeerId());
|
||||||
// Digging completed -> under
|
// Digging completed -> under
|
||||||
if (action == 2) {
|
if (action == INTERACT_DIGGING_COMPLETED) {
|
||||||
v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
|
v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
|
||||||
client->SetBlockNotSent(blockpos);
|
client->SetBlockNotSent(blockpos);
|
||||||
}
|
}
|
||||||
// Placement -> above
|
// Placement -> above
|
||||||
else if (action == 3) {
|
else if (action == INTERACT_PLACE) {
|
||||||
v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_above, BS));
|
v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_above, BS));
|
||||||
client->SetBlockNotSent(blockpos);
|
client->SetBlockNotSent(blockpos);
|
||||||
}
|
}
|
||||||
@ -1098,10 +1094,10 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
|
|||||||
static thread_local const bool enable_anticheat =
|
static thread_local const bool enable_anticheat =
|
||||||
!g_settings->getBool("disable_anticheat");
|
!g_settings->getBool("disable_anticheat");
|
||||||
|
|
||||||
if ((action == 0 || action == 2 || action == 3 || action == 4) &&
|
if ((action == INTERACT_START_DIGGING || action == INTERACT_DIGGING_COMPLETED ||
|
||||||
|
action == INTERACT_PLACE || action == INTERACT_USE) &&
|
||||||
enable_anticheat && !isSingleplayer()) {
|
enable_anticheat && !isSingleplayer()) {
|
||||||
float d = playersao->getEyePosition()
|
float d = playersao->getEyePosition().getDistanceFrom(pointed_pos_under);
|
||||||
.getDistanceFrom(pointed_pos_under);
|
|
||||||
|
|
||||||
if (!checkInteractDistance(player, d, pointed.dump())) {
|
if (!checkInteractDistance(player, d, pointed.dump())) {
|
||||||
// Re-send block to revert change on client-side
|
// Re-send block to revert change on client-side
|
||||||
@ -1121,7 +1117,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
|
|||||||
/*
|
/*
|
||||||
0: start digging or punch object
|
0: start digging or punch object
|
||||||
*/
|
*/
|
||||||
if (action == 0) {
|
if (action == INTERACT_START_DIGGING) {
|
||||||
if (pointed.type == POINTEDTHING_NODE) {
|
if (pointed.type == POINTEDTHING_NODE) {
|
||||||
MapNode n(CONTENT_IGNORE);
|
MapNode n(CONTENT_IGNORE);
|
||||||
bool pos_ok;
|
bool pos_ok;
|
||||||
@ -1174,18 +1170,18 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
|
|||||||
PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, pointed_object));
|
PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, pointed_object));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // action == 0
|
} // action == INTERACT_START_DIGGING
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1: stop digging
|
1: stop digging
|
||||||
*/
|
*/
|
||||||
else if (action == 1) {
|
else if (action == INTERACT_STOP_DIGGING) {
|
||||||
} // action == 1
|
} // action == INTERACT_STOP_DIGGING
|
||||||
|
|
||||||
/*
|
/*
|
||||||
2: Digging completed
|
2: Digging completed
|
||||||
*/
|
*/
|
||||||
else if (action == 2) {
|
else if (action == INTERACT_DIGGING_COMPLETED) {
|
||||||
// Only digging of nodes
|
// Only digging of nodes
|
||||||
if (pointed.type == POINTEDTHING_NODE) {
|
if (pointed.type == POINTEDTHING_NODE) {
|
||||||
bool pos_ok;
|
bool pos_ok;
|
||||||
@ -1281,12 +1277,12 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
|
|||||||
client->ResendBlockIfOnWire(blockpos);
|
client->ResendBlockIfOnWire(blockpos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // action == 2
|
} // action == INTERACT_DIGGING_COMPLETED
|
||||||
|
|
||||||
/*
|
/*
|
||||||
3: place block or right-click object
|
3: place block or right-click object
|
||||||
*/
|
*/
|
||||||
else if (action == 3) {
|
else if (action == INTERACT_PLACE) {
|
||||||
ItemStack item = playersao->getWieldedItem();
|
ItemStack item = playersao->getWieldedItem();
|
||||||
|
|
||||||
// Reset build time counter
|
// Reset build time counter
|
||||||
@ -1335,12 +1331,12 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
|
|||||||
client->ResendBlockIfOnWire(blockpos2);
|
client->ResendBlockIfOnWire(blockpos2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // action == 3
|
} // action == INTERACT_PLACE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
4: use
|
4: use
|
||||||
*/
|
*/
|
||||||
else if (action == 4) {
|
else if (action == INTERACT_USE) {
|
||||||
ItemStack item = playersao->getWieldedItem();
|
ItemStack item = playersao->getWieldedItem();
|
||||||
|
|
||||||
actionstream << player->getName() << " uses " << item.name
|
actionstream << player->getName() << " uses " << item.name
|
||||||
@ -1354,12 +1350,12 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // action == 4
|
} // action == INTERACT_USE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
5: rightclick air
|
5: rightclick air
|
||||||
*/
|
*/
|
||||||
else if (action == 5) {
|
else if (action == INTERACT_ACTIVATE) {
|
||||||
ItemStack item = playersao->getWieldedItem();
|
ItemStack item = playersao->getWieldedItem();
|
||||||
|
|
||||||
actionstream << player->getName() << " activates "
|
actionstream << player->getName() << " activates "
|
||||||
@ -1371,7 +1367,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
|
|||||||
SendInventory(playersao);
|
SendInventory(playersao);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // action == INTERACT_ACTIVATE
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user