Merge pull request #36829 from MrStonedOne/onclick_rework

[s]Minor Refactor of click code, anti-auto clicker protection
This commit is contained in:
vuonojenmustaturska
2018-04-01 16:23:54 +03:00
committed by CitadelStationBot
parent 75a49c53c8
commit ae61521e67
7 changed files with 180 additions and 99 deletions

View File

@@ -1,98 +0,0 @@
/client
var/list/atom/selected_target[2]
var/obj/item/active_mousedown_item = null
var/mouseParams = ""
var/mouseLocation = null
var/mouseObject = null
var/mouseControlObject = null
/client/MouseDown(object, location, control, params)
var/delay = mob.CanMobAutoclick(object, location, params)
if(delay)
selected_target[1] = object
selected_target[2] = params
while(selected_target[1])
Click(selected_target[1], location, control, selected_target[2])
sleep(delay)
active_mousedown_item = mob.canMobMousedown(object, location, params)
if(active_mousedown_item)
active_mousedown_item.onMouseDown(object, location, params, mob)
/client/MouseUp(object, location, control, params)
selected_target[1] = null
if(active_mousedown_item)
active_mousedown_item.onMouseUp(object, location, params, mob)
active_mousedown_item = null
/mob/proc/CanMobAutoclick(object, location, params)
/mob/living/carbon/CanMobAutoclick(atom/object, location, params)
if(!object.IsAutoclickable())
return
var/obj/item/h = get_active_held_item()
if(h)
. = h.CanItemAutoclick(object, location, params)
/mob/proc/canMobMousedown(object, location, params)
/mob/living/carbon/canMobMousedown(atom/object, location, params)
var/obj/item/H = get_active_held_item()
if(H)
. = H.canItemMouseDown(object, location, params)
/obj/item/proc/CanItemAutoclick(object, location, params)
/obj/item/proc/canItemMouseDown(object, location, params)
if(canMouseDown)
return src
/obj/item/proc/onMouseDown(object, location, params, mob)
return
/obj/item/proc/onMouseUp(object, location, params, mob)
return
/obj/item
var/canMouseDown = FALSE
/obj/item/gun
var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds
/obj/item/gun/CanItemAutoclick(object, location, params)
. = automatic
/atom/proc/IsAutoclickable()
. = 1
/obj/screen/IsAutoclickable()
. = 0
/obj/screen/click_catcher/IsAutoclickable()
. = 1
//Please don't roast me too hard
/client/MouseMove(object,location,control,params)
mouseParams = params
mouseLocation = location
mouseObject = object
mouseControlObject = control
if(mob && LAZYLEN(mob.mousemove_intercept_objects))
for(var/datum/D in mob.mousemove_intercept_objects)
D.onMouseMove(object, location, control, params)
/datum/proc/onMouseMove(object, location, control, params)
return
/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params)
mouseParams = params
mouseLocation = over_location
mouseObject = over_object
mouseControlObject = over_control
if(selected_target[1] && over_object && over_object.IsAutoclickable())
selected_target[1] = over_object
selected_target[2] = params
if(active_mousedown_item)
active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
return

View File

@@ -19,3 +19,120 @@
// recieve a mousedrop // recieve a mousedrop
/atom/proc/MouseDrop_T(atom/dropping, mob/user) /atom/proc/MouseDrop_T(atom/dropping, mob/user)
return return
/client
var/list/atom/selected_target[2]
var/obj/item/active_mousedown_item = null
var/mouseParams = ""
var/mouseLocation = null
var/mouseObject = null
var/mouseControlObject = null
var/middragtime = 0
var/atom/middragatom
/client/MouseDown(object, location, control, params)
var/delay = mob.CanMobAutoclick(object, location, params)
if(delay)
selected_target[1] = object
selected_target[2] = params
while(selected_target[1])
Click(selected_target[1], location, control, selected_target[2])
sleep(delay)
active_mousedown_item = mob.canMobMousedown(object, location, params)
if(active_mousedown_item)
active_mousedown_item.onMouseDown(object, location, params, mob)
/client/MouseUp(object, location, control, params)
selected_target[1] = null
if(active_mousedown_item)
active_mousedown_item.onMouseUp(object, location, params, mob)
active_mousedown_item = null
/mob/proc/CanMobAutoclick(object, location, params)
/mob/living/carbon/CanMobAutoclick(atom/object, location, params)
if(!object.IsAutoclickable())
return
var/obj/item/h = get_active_held_item()
if(h)
. = h.CanItemAutoclick(object, location, params)
/mob/proc/canMobMousedown(object, location, params)
/mob/living/carbon/canMobMousedown(atom/object, location, params)
var/obj/item/H = get_active_held_item()
if(H)
. = H.canItemMouseDown(object, location, params)
/obj/item/proc/CanItemAutoclick(object, location, params)
/obj/item/proc/canItemMouseDown(object, location, params)
if(canMouseDown)
return src
/obj/item/proc/onMouseDown(object, location, params, mob)
return
/obj/item/proc/onMouseUp(object, location, params, mob)
return
/obj/item
var/canMouseDown = FALSE
/obj/item/gun
var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds
/obj/item/gun/CanItemAutoclick(object, location, params)
. = automatic
/atom/proc/IsAutoclickable()
. = 1
/obj/screen/IsAutoclickable()
. = 0
/obj/screen/click_catcher/IsAutoclickable()
. = 1
//Please don't roast me too hard
/client/MouseMove(object,location,control,params)
mouseParams = params
mouseLocation = location
mouseObject = object
mouseControlObject = control
if(mob && LAZYLEN(mob.mousemove_intercept_objects))
for(var/datum/D in mob.mousemove_intercept_objects)
D.onMouseMove(object, location, control, params)
/datum/proc/onMouseMove(object, location, control, params)
return
/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params)
var/list/L = params2list(params)
if (L["middle"])
if (src_object && src_location != over_location)
middragtime = world.time
middragatom = src_object
else
middragtime = 0
middragatom = null
mouseParams = params
mouseLocation = over_location
mouseObject = over_object
mouseControlObject = over_control
if(selected_target[1] && over_object && over_object.IsAutoclickable())
selected_target[1] = over_object
selected_target[2] = params
if(active_mousedown_item)
active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
return
/client/MouseDrop(src_object, over_object, src_location, over_location, src_control, over_control, params)
if (middragatom == src_object)
middragtime = 0
middragatom = null
..()

View File

@@ -344,6 +344,14 @@
config_entry_value = null config_entry_value = null
min_val = 0 min_val = 0
/datum/config_entry/number/minute_click_limit
config_entry_value = 400
min_val = 0
/datum/config_entry/number/second_click_limit
config_entry_value = 15
min_val = 0
/datum/config_entry/number/error_cooldown // The "cooldown" time for each occurrence of a unique error /datum/config_entry/number/error_cooldown // The "cooldown" time for each occurrence of a unique error
config_entry_value = 600 config_entry_value = 600
min_val = 0 min_val = 0

View File

@@ -62,6 +62,7 @@
var/inprefs = FALSE var/inprefs = FALSE
var/list/topiclimiter var/list/topiclimiter
var/list/clicklimiter
var/datum/chatOutput/chatOutput var/datum/chatOutput/chatOutput

View File

@@ -650,6 +650,49 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
message_admins("<span class='adminnotice'>Proxy Detection: [key_name_admin(src)] IP intel rated [res.intel*100]% likely to be a Proxy/VPN.</span>") message_admins("<span class='adminnotice'>Proxy Detection: [key_name_admin(src)] IP intel rated [res.intel*100]% likely to be a Proxy/VPN.</span>")
ip_intel = res.intel ip_intel = res.intel
/client/Click(atom/object, atom/location, control, params)
var/ab = FALSE
var/list/L = params2list(params)
if (object && object == middragatom && L["left"])
ab = max(0, 5 SECONDS-(world.time-middragtime)*0.1)
var/mcl = CONFIG_GET(number/minute_click_limit)
if (!holder && mcl)
var/minute = round(world.time, 600)
if (!clicklimiter)
clicklimiter = new(LIMITER_SIZE)
if (minute != clicklimiter[CURRENT_MINUTE])
clicklimiter[CURRENT_MINUTE] = minute
clicklimiter[MINUTE_COUNT] = 0
clicklimiter[MINUTE_COUNT] += 1+(ab)
if (clicklimiter[MINUTE_COUNT] > mcl)
var/msg = "Your previous click was ignored because you've done too many in a minute."
if (minute != clicklimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them)
clicklimiter[ADMINSWARNED_AT] = minute
msg += " Administrators have been informed."
if (ab)
log_game("[key_name(src)] is using the middle click aimbot exploit")
message_admins("[key_name_admin(src)] [ADMIN_FLW(usr)] [ADMIN_KICK(usr)] is using the middle click aimbot exploit</span>")
add_system_note("aimbot", "Is using the middle click aimbot exploit")
log_game("[key_name(src)] Has hit the per-minute click limit of [mcl] clicks in a given game minute")
message_admins("[key_name_admin(src)] [ADMIN_FLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute click limit of [mcl] clicks in a given game minute")
to_chat(src, "<span class='danger'>[msg]</span>")
return
var/scl = CONFIG_GET(number/second_click_limit)
if (!holder && scl)
var/second = round(world.time, 10)
if (!clicklimiter)
clicklimiter = new(LIMITER_SIZE)
if (second != clicklimiter[CURRENT_SECOND])
clicklimiter[CURRENT_SECOND] = second
clicklimiter[SECOND_COUNT] = 0
clicklimiter[SECOND_COUNT] += 1+(!!ab)
if (clicklimiter[SECOND_COUNT] > scl)
to_chat(src, "<span class='danger'>Your previous click was ignored because you've done too many in a second</span>")
return
..()
/client/proc/add_verbs_from_config() /client/proc/add_verbs_from_config()
if(CONFIG_GET(flag/see_own_notes)) if(CONFIG_GET(flag/see_own_notes))

View File

@@ -386,6 +386,17 @@ SECOND_TOPIC_LIMIT 10
MINUTE_TOPIC_LIMIT 100 MINUTE_TOPIC_LIMIT 100
## CLICK RATE LIMITING
## Same as above, but applies to clicking on objects in the game window.
## This should be a higher then the interface limit to allow for the spam clickly nature of most battles.
## Admins are exempt from these limits.
## Hitting the minute limit notifies admins.
## Set to 0 to disable.
SECOND_CLICK_LIMIT 15
MINUTE_CLICK_LIMIT 400
##Error handling related options ##Error handling related options
## The "cooldown" time for each occurence of a unique error ## The "cooldown" time for each occurence of a unique error
#ERROR_COOLDOWN 600 #ERROR_COOLDOWN 600

View File

@@ -149,7 +149,6 @@
#include "code\_js\menus.dm" #include "code\_js\menus.dm"
#include "code\_onclick\adjacent.dm" #include "code\_onclick\adjacent.dm"
#include "code\_onclick\ai.dm" #include "code\_onclick\ai.dm"
#include "code\_onclick\autoclick.dm"
#include "code\_onclick\click.dm" #include "code\_onclick\click.dm"
#include "code\_onclick\cyborg.dm" #include "code\_onclick\cyborg.dm"
#include "code\_onclick\drag_drop.dm" #include "code\_onclick\drag_drop.dm"