mirror of
https://github.com/dekuNukem/USB4VC.git
synced 2025-10-31 11:26:46 -07:00
added default ibmpc ggp mapping
This commit is contained in:
@@ -1,56 +0,0 @@
|
||||
BTN_LEFT = 0x110
|
||||
BTN_RIGHT = 0x111
|
||||
BTN_MIDDLE = 0x112
|
||||
BTN_SIDE = 0x113
|
||||
BTN_EXTRA = 0x114
|
||||
BTN_FORWARD = 0x115
|
||||
BTN_BACK = 0x116
|
||||
BTN_TASK = 0x117
|
||||
|
||||
|
||||
REL_X = 0x00
|
||||
REL_Y = 0x01
|
||||
REL_Z = 0x02
|
||||
REL_RX = 0x03
|
||||
REL_RY = 0x04
|
||||
REL_RZ = 0x05
|
||||
REL_HWHEEL = 0x06
|
||||
REL_DIAL = 0x07
|
||||
REL_WHEEL = 0x08
|
||||
REL_MISC = 0x09
|
||||
|
||||
KB_KEY_A = (30, 'pb_kb')
|
||||
KB_KEY_B = (48, 'pb_kb')
|
||||
KB_KEY_C = (46, 'pb_kb')
|
||||
KB_KEY_D = (32, 'pb_kb')
|
||||
KB_KEY_UP = (103, 'pb_kb')
|
||||
KB_KEY_DOWN = (108, 'pb_kb')
|
||||
KB_KEY_LEFT = (105, 'pb_kb')
|
||||
KB_KEY_RIGHT = (106, 'pb_kb')
|
||||
KB_KEY_LCTRL = (29, 'pb_kb')
|
||||
MOUSE_BTN_LEFT = (BTN_LEFT, 'mouse_btn')
|
||||
MOUSE_BTN_MIDDLE = (BTN_MIDDLE, 'mouse_btn')
|
||||
MOUSE_BTN_RIGHT = (BTN_RIGHT, 'mouse_btn')
|
||||
MOUSE_BTN_SIDE = (BTN_SIDE, 'mouse_btn')
|
||||
MOUSE_BTN_EXTRA = (BTN_EXTRA, 'mouse_btn')
|
||||
MOUSE_X = (REL_X, 'mouse_axes')
|
||||
MOUSE_Y = (REL_Y, 'mouse_axes')
|
||||
MOUSE_SCROLL = (REL_WHEEL, 'mouse_axes')
|
||||
IBMPC_GGP_BTN_1 = ('IBMGGP_BTN_1', 'pb_gp_btn')
|
||||
IBMPC_GGP_BTN_2 = ('IBMGGP_BTN_2', 'pb_gp_btn')
|
||||
IBMPC_GGP_BTN_3 = ('IBMGGP_BTN_3', 'pb_gp_btn')
|
||||
IBMPC_GGP_BTN_4 = ('IBMGGP_BTN_4', 'pb_gp_btn')
|
||||
IBMPC_GGP_JS1_X = ('IBMGGP_JS1_X', 'pb_gp_axes')
|
||||
IBMPC_GGP_JS1_Y = ('IBMGGP_JS1_Y', 'pb_gp_axes')
|
||||
IBMPC_GGP_JS2_X = ('IBMGGP_JS2_X', 'pb_gp_axes')
|
||||
IBMPC_GGP_JS2_Y = ('IBMGGP_JS2_Y', 'pb_gp_axes')
|
||||
|
||||
IBMPC_GGP_JS1_X_POS = ('IBMGGP_JS1_XP', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS1_X_NEG = ('IBMGGP_JS1_XN', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS1_Y_POS = ('IBMGGP_JS1_YP', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS1_Y_NEG = ('IBMGGP_JS1_YN', 'pb_gp_half_axes')
|
||||
|
||||
IBMPC_GGP_JS2_X_POS = ('IBMGGP_JS2_XP', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS2_X_NEG = ('IBMGGP_JS2_XN', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS2_Y_POS = ('IBMGGP_JS2_YP', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS2_Y_NEG = ('IBMGGP_JS2_YN', 'pb_gp_half_axes')
|
||||
@@ -1,4 +1,5 @@
|
||||
this_device = ooopened_device_dict[key]
|
||||
print(source_code, source_type, target_info)
|
||||
|
||||
def raw_input_event_worker():
|
||||
mouse_status_dict = {}
|
||||
|
||||
@@ -3,3 +3,60 @@ SPI_MOSI_MSG_TYPE_SET_PROTOCOL = 2
|
||||
|
||||
RPI_APP_VERSION_TUPLE = (0, 0, 1)
|
||||
set_protocl_spi_msg_template = [SPI_MOSI_MAGIC, 0, SPI_MOSI_MSG_TYPE_SET_PROTOCOL] + [0]*29
|
||||
|
||||
BTN_LEFT = 0x110
|
||||
BTN_RIGHT = 0x111
|
||||
BTN_MIDDLE = 0x112
|
||||
BTN_SIDE = 0x113
|
||||
BTN_EXTRA = 0x114
|
||||
BTN_FORWARD = 0x115
|
||||
BTN_BACK = 0x116
|
||||
BTN_TASK = 0x117
|
||||
|
||||
|
||||
REL_X = 0x00
|
||||
REL_Y = 0x01
|
||||
REL_Z = 0x02
|
||||
REL_RX = 0x03
|
||||
REL_RY = 0x04
|
||||
REL_RZ = 0x05
|
||||
REL_HWHEEL = 0x06
|
||||
REL_DIAL = 0x07
|
||||
REL_WHEEL = 0x08
|
||||
REL_MISC = 0x09
|
||||
|
||||
KB_KEY_A = (30, 'pb_kb')
|
||||
KB_KEY_B = (48, 'pb_kb')
|
||||
KB_KEY_C = (46, 'pb_kb')
|
||||
KB_KEY_D = (32, 'pb_kb')
|
||||
KB_KEY_UP = (103, 'pb_kb')
|
||||
KB_KEY_DOWN = (108, 'pb_kb')
|
||||
KB_KEY_LEFT = (105, 'pb_kb')
|
||||
KB_KEY_RIGHT = (106, 'pb_kb')
|
||||
KB_KEY_LCTRL = (29, 'pb_kb')
|
||||
MOUSE_BTN_LEFT = (BTN_LEFT, 'mouse_btn')
|
||||
MOUSE_BTN_MIDDLE = (BTN_MIDDLE, 'mouse_btn')
|
||||
MOUSE_BTN_RIGHT = (BTN_RIGHT, 'mouse_btn')
|
||||
MOUSE_BTN_SIDE = (BTN_SIDE, 'mouse_btn')
|
||||
MOUSE_BTN_EXTRA = (BTN_EXTRA, 'mouse_btn')
|
||||
MOUSE_X = (REL_X, 'mouse_axes')
|
||||
MOUSE_Y = (REL_Y, 'mouse_axes')
|
||||
MOUSE_SCROLL = (REL_WHEEL, 'mouse_axes')
|
||||
IBMPC_GGP_BTN_1 = ('IBMGGP_BTN_1', 'pb_gp_btn')
|
||||
IBMPC_GGP_BTN_2 = ('IBMGGP_BTN_2', 'pb_gp_btn')
|
||||
IBMPC_GGP_BTN_3 = ('IBMGGP_BTN_3', 'pb_gp_btn')
|
||||
IBMPC_GGP_BTN_4 = ('IBMGGP_BTN_4', 'pb_gp_btn')
|
||||
IBMPC_GGP_JS1_X = ('IBMGGP_JS1_X', 'pb_gp_axes')
|
||||
IBMPC_GGP_JS1_Y = ('IBMGGP_JS1_Y', 'pb_gp_axes')
|
||||
IBMPC_GGP_JS2_X = ('IBMGGP_JS2_X', 'pb_gp_axes')
|
||||
IBMPC_GGP_JS2_Y = ('IBMGGP_JS2_Y', 'pb_gp_axes')
|
||||
|
||||
IBMPC_GGP_JS1_X_POS = ('IBMGGP_JS1_XP', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS1_X_NEG = ('IBMGGP_JS1_XN', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS1_Y_POS = ('IBMGGP_JS1_YP', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS1_Y_NEG = ('IBMGGP_JS1_YN', 'pb_gp_half_axes')
|
||||
|
||||
IBMPC_GGP_JS2_X_POS = ('IBMGGP_JS2_XP', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS2_X_NEG = ('IBMGGP_JS2_XN', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS2_Y_POS = ('IBMGGP_JS2_YP', 'pb_gp_half_axes')
|
||||
IBMPC_GGP_JS2_Y_NEG = ('IBMGGP_JS2_YN', 'pb_gp_half_axes')
|
||||
|
||||
@@ -11,7 +11,6 @@ import RPi.GPIO as GPIO
|
||||
import usb4vc_usb_scan
|
||||
import usb4vc_shared
|
||||
import json
|
||||
import map_codes
|
||||
|
||||
data_dir_path = os.path.join(os.path.expanduser('~'), 'usb4vc_data')
|
||||
config_file_path = os.path.join(data_dir_path, 'config.json')
|
||||
@@ -58,19 +57,6 @@ PBOARD_ID_ADB = 2
|
||||
pboard_info_spi_msg = [0] * 32
|
||||
this_pboard_id = PBOARD_ID_UNKNOWN
|
||||
|
||||
PROTOCOL_OFF = {'pid':0, 'display_name':"OFF", 'is_custom':0}
|
||||
PROTOCOL_AT_PS2_KB = {'pid':1, 'display_name':"AT/PS2", 'is_custom':0}
|
||||
PROTOCOL_XT_KB = {'pid':2, 'display_name':"PC XT", 'is_custom':0}
|
||||
PROTOCOL_ADB_KB = {'pid':3, 'display_name':"ADB", 'is_custom':0}
|
||||
PROTOCOL_PS2_MOUSE = {'pid':4, 'display_name':"PS/2", 'is_custom':0}
|
||||
PROTOCOL_MICROSOFT_SERIAL_MOUSE = {'pid':5, 'display_name':"MS Serial", 'is_custom':0}
|
||||
PROTOCOL_ADB_MOUSE = {'pid':6, 'display_name':"ADB", 'is_custom':0}
|
||||
PROTOCOL_GENERIC_GAMEPORT_GAMEPAD = {'pid':7, 'display_name':"Generic PC", 'is_custom':0}
|
||||
PROTOCOL_GAMEPORT_GRAVIS_GAMEPAD = {'pid':8, 'display_name':"Gravis Pro", 'is_custom':0}
|
||||
PROTOCOL_GAMEPORT_MICROSOFT_SIDEWINDER = {'pid':9, 'display_name':"MS Sidewinder", 'is_custom':0}
|
||||
PROTOCOL_RAW_KEYBOARD = {'pid':125, 'display_name':"Raw data", 'is_custom':0}
|
||||
PROTOCOL_RAW_MOUSE = {'pid':126, 'display_name':"Raw data", 'is_custom':0}
|
||||
PROTOCOL_RAW_GAMEPAD = {'pid':127, 'display_name':"Raw data", 'is_custom':0}
|
||||
|
||||
USBGP_BTN_SOUTH = 0x130
|
||||
USBGP_BTN_EAST = 0x131
|
||||
@@ -102,6 +88,37 @@ USBGP_ABS_RZ = 0x05 # right analog trigger
|
||||
USBGP_ABS_HAT0X = 0x10 # D-pad X
|
||||
USBGP_ABS_HAT0Y = 0x11 # D-pad Y
|
||||
|
||||
IBMPC_GGP_DEAULT_MAPPING = {
|
||||
# buttons to buttons
|
||||
USBGP_BTN_X: {'code':usb4vc_shared.IBMPC_GGP_BTN_2[0], 'type':usb4vc_shared.IBMPC_GGP_BTN_2[1]},
|
||||
USBGP_BTN_B: {'code':usb4vc_shared.IBMPC_GGP_BTN_3[0], 'type':usb4vc_shared.IBMPC_GGP_BTN_3[1]},
|
||||
USBGP_BTN_Y: {'code':usb4vc_shared.IBMPC_GGP_BTN_4[0], 'type':usb4vc_shared.IBMPC_GGP_BTN_4[1]},
|
||||
USBGP_BTN_A: {'code':usb4vc_shared.IBMPC_GGP_BTN_1[0], 'type':usb4vc_shared.IBMPC_GGP_BTN_1[1]},
|
||||
USBGP_BTN_TL: {'code':usb4vc_shared.IBMPC_GGP_BTN_1[0], 'type':usb4vc_shared.IBMPC_GGP_BTN_1[1]},
|
||||
USBGP_BTN_TR: {'code':usb4vc_shared.IBMPC_GGP_BTN_2[0], 'type':usb4vc_shared.IBMPC_GGP_BTN_2[1]},
|
||||
# analog stick to analog stick
|
||||
USBGP_ABS_X: {'code':usb4vc_shared.IBMPC_GGP_JS1_X[0], 'type':usb4vc_shared.IBMPC_GGP_JS1_X[1]},
|
||||
USBGP_ABS_Y: {'code':usb4vc_shared.IBMPC_GGP_JS1_Y[0], 'type':usb4vc_shared.IBMPC_GGP_JS1_Y[1]},
|
||||
USBGP_ABS_HAT0X: {'code':usb4vc_shared.IBMPC_GGP_JS1_X[0], 'type':usb4vc_shared.IBMPC_GGP_JS1_X[1]},
|
||||
USBGP_ABS_HAT0Y: {'code':usb4vc_shared.IBMPC_GGP_JS1_Y[0], 'type':usb4vc_shared.IBMPC_GGP_JS1_Y[1]},
|
||||
USBGP_ABS_RX: {'code':usb4vc_shared.IBMPC_GGP_JS2_X[0], 'type':usb4vc_shared.IBMPC_GGP_JS2_X[1]},
|
||||
USBGP_ABS_RY: {'code':usb4vc_shared.IBMPC_GGP_JS2_Y[0], 'type':usb4vc_shared.IBMPC_GGP_JS2_Y[1]},
|
||||
}
|
||||
|
||||
PROTOCOL_OFF = {'pid':0, 'display_name':"OFF"}
|
||||
PROTOCOL_AT_PS2_KB = {'pid':1, 'display_name':"AT/PS2"}
|
||||
PROTOCOL_XT_KB = {'pid':2, 'display_name':"PC XT"}
|
||||
PROTOCOL_ADB_KB = {'pid':3, 'display_name':"ADB"}
|
||||
PROTOCOL_PS2_MOUSE = {'pid':4, 'display_name':"PS/2"}
|
||||
PROTOCOL_MICROSOFT_SERIAL_MOUSE = {'pid':5, 'display_name':"MS Serial"}
|
||||
PROTOCOL_ADB_MOUSE = {'pid':6, 'display_name':"ADB"}
|
||||
PROTOCOL_GENERIC_GAMEPORT_GAMEPAD = {'pid':7, 'display_name':"Generic PC", 'mapping':IBMPC_GGP_DEAULT_MAPPING}
|
||||
PROTOCOL_GAMEPORT_GRAVIS_GAMEPAD = {'pid':8, 'display_name':"Gravis Pro"}
|
||||
PROTOCOL_GAMEPORT_MICROSOFT_SIDEWINDER = {'pid':9, 'display_name':"MS Sidewinder"}
|
||||
PROTOCOL_RAW_KEYBOARD = {'pid':125, 'display_name':"Raw data"}
|
||||
PROTOCOL_RAW_MOUSE = {'pid':126, 'display_name':"Raw data"}
|
||||
PROTOCOL_RAW_GAMEPAD = {'pid':127, 'display_name':"Raw data"}
|
||||
|
||||
custom_profile_1 = {
|
||||
'name':'test',
|
||||
'type':'plist_gamepad',
|
||||
@@ -110,26 +127,26 @@ custom_profile_1 = {
|
||||
'mapping':
|
||||
{
|
||||
# buttons to buttons
|
||||
USBGP_BTN_X: {'code':map_codes.MOUSE_BTN_LEFT[0], 'type':map_codes.MOUSE_BTN_LEFT[1]},
|
||||
USBGP_BTN_B: {'code':map_codes.MOUSE_BTN_RIGHT[0], 'type':map_codes.MOUSE_BTN_RIGHT[1]},
|
||||
USBGP_BTN_Y: {'code':map_codes.MOUSE_BTN_MIDDLE[0], 'type':map_codes.MOUSE_BTN_MIDDLE[1]},
|
||||
USBGP_BTN_A: {'code':map_codes.MOUSE_BTN_MIDDLE[0], 'type':map_codes.MOUSE_BTN_MIDDLE[1]},
|
||||
USBGP_BTN_X: {'code':usb4vc_shared.MOUSE_BTN_LEFT[0], 'type':usb4vc_shared.MOUSE_BTN_LEFT[1]},
|
||||
USBGP_BTN_B: {'code':usb4vc_shared.MOUSE_BTN_RIGHT[0], 'type':usb4vc_shared.MOUSE_BTN_RIGHT[1]},
|
||||
USBGP_BTN_Y: {'code':usb4vc_shared.MOUSE_BTN_MIDDLE[0], 'type':usb4vc_shared.MOUSE_BTN_MIDDLE[1]},
|
||||
USBGP_BTN_A: {'code':usb4vc_shared.MOUSE_BTN_MIDDLE[0], 'type':usb4vc_shared.MOUSE_BTN_MIDDLE[1]},
|
||||
# analog stick to analog stick
|
||||
USBGP_ABS_X: {'code':map_codes.MOUSE_X[0], 'type':map_codes.MOUSE_X[1], 'deadzone':20},
|
||||
USBGP_ABS_Y: {'code':map_codes.MOUSE_Y[0], 'type':map_codes.MOUSE_Y[1], 'deadzone':20},
|
||||
USBGP_ABS_HAT0X: {'code':map_codes.IBMPC_GGP_JS1_X[0], 'type':map_codes.IBMPC_GGP_JS1_X[1]},
|
||||
USBGP_ABS_HAT0Y: {'code':map_codes.IBMPC_GGP_JS1_Y[0], 'type':map_codes.IBMPC_GGP_JS1_Y[1]},
|
||||
USBGP_ABS_X: {'code':usb4vc_shared.MOUSE_X[0], 'type':usb4vc_shared.MOUSE_X[1], 'deadzone':20},
|
||||
USBGP_ABS_Y: {'code':usb4vc_shared.MOUSE_Y[0], 'type':usb4vc_shared.MOUSE_Y[1], 'deadzone':20},
|
||||
USBGP_ABS_HAT0X: {'code':usb4vc_shared.IBMPC_GGP_JS1_X[0], 'type':usb4vc_shared.IBMPC_GGP_JS1_X[1]},
|
||||
USBGP_ABS_HAT0Y: {'code':usb4vc_shared.IBMPC_GGP_JS1_Y[0], 'type':usb4vc_shared.IBMPC_GGP_JS1_Y[1]},
|
||||
# buttons to analog stick
|
||||
USBGP_BTN_TL: {'code':map_codes.IBMPC_GGP_BTN_1[0], 'type':map_codes.IBMPC_GGP_BTN_1[1]},
|
||||
USBGP_BTN_TR: {'code':map_codes.IBMPC_GGP_BTN_2[0], 'type':map_codes.IBMPC_GGP_BTN_2[1]},
|
||||
USBGP_BTN_TL: {'code':usb4vc_shared.IBMPC_GGP_BTN_1[0], 'type':usb4vc_shared.IBMPC_GGP_BTN_1[1]},
|
||||
USBGP_BTN_TR: {'code':usb4vc_shared.IBMPC_GGP_BTN_2[0], 'type':usb4vc_shared.IBMPC_GGP_BTN_2[1]},
|
||||
# buttons to keyboard key
|
||||
USBGP_BTN_START: {'code':map_codes.KB_KEY_A[0], 'type':map_codes.KB_KEY_A[1]},
|
||||
USBGP_BTN_SELECT: {'code':map_codes.KB_KEY_B[0], 'type':map_codes.KB_KEY_B[1]},
|
||||
USBGP_BTN_TL: {'code':map_codes.IBMPC_GGP_JS1_X_NEG[0], 'type':map_codes.IBMPC_GGP_JS1_X_NEG[1]},
|
||||
USBGP_BTN_TR: {'code':map_codes.IBMPC_GGP_JS1_X_POS[0], 'type':map_codes.IBMPC_GGP_JS1_X_POS[1]},
|
||||
USBGP_BTN_START: {'code':usb4vc_shared.KB_KEY_A[0], 'type':usb4vc_shared.KB_KEY_A[1]},
|
||||
USBGP_BTN_SELECT: {'code':usb4vc_shared.KB_KEY_B[0], 'type':usb4vc_shared.KB_KEY_B[1]},
|
||||
USBGP_BTN_TL: {'code':usb4vc_shared.IBMPC_GGP_JS1_X_NEG[0], 'type':usb4vc_shared.IBMPC_GGP_JS1_X_NEG[1]},
|
||||
USBGP_BTN_TR: {'code':usb4vc_shared.IBMPC_GGP_JS1_X_POS[0], 'type':usb4vc_shared.IBMPC_GGP_JS1_X_POS[1]},
|
||||
# analog stick to keyboard key
|
||||
USBGP_ABS_RX: {'type':'pb_kb', 'code':map_codes.KB_KEY_RIGHT[0], 'code_neg':map_codes.KB_KEY_LEFT[0], 'deadzone':64},
|
||||
USBGP_ABS_RY: {'type':'pb_kb', 'code':map_codes.KB_KEY_DOWN[0], 'code_neg':map_codes.KB_KEY_UP[0], 'deadzone':64},
|
||||
USBGP_ABS_RX: {'type':'pb_kb', 'code':usb4vc_shared.KB_KEY_RIGHT[0], 'code_neg':usb4vc_shared.KB_KEY_LEFT[0], 'deadzone':64},
|
||||
USBGP_ABS_RY: {'type':'pb_kb', 'code':usb4vc_shared.KB_KEY_DOWN[0], 'code_neg':usb4vc_shared.KB_KEY_UP[0], 'deadzone':64},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +436,7 @@ def ui_init():
|
||||
# load custom profile mapping into protocol list
|
||||
for item in custom_profile_list:
|
||||
if item['bid'] == this_pboard_id and item['type'] in pboard_database[this_pboard_id]:
|
||||
this_profile = {'pid':item['pid'], 'display_name':item['name'], 'is_custom':1, 'mapping':item['mapping']}
|
||||
this_profile = {'pid':item['pid'], 'display_name':item['name'], 'mapping':item['mapping']}
|
||||
pboard_database[this_pboard_id][item['type']].append(this_profile)
|
||||
pboard_database[this_pboard_id]['hw_rev'] = pboard_info_spi_msg[4]
|
||||
pboard_database[this_pboard_id]['fw_ver'] = (pboard_info_spi_msg[5], pboard_info_spi_msg[6], pboard_info_spi_msg[7])
|
||||
|
||||
@@ -243,7 +243,6 @@ def make_generic_gamepad_spi_packet(gp_status_dict, gp_id, axes_info, mapping_in
|
||||
source_type, target_info = find_keycode_in_mapping(source_code, mapping_info['mapping'])
|
||||
if target_info is None:
|
||||
continue
|
||||
print(source_code, source_type, target_info)
|
||||
target_code = target_info['code']
|
||||
target_type = target_info['type']
|
||||
|
||||
@@ -353,7 +352,7 @@ def make_generic_gamepad_spi_packet(gp_status_dict, gp_id, axes_info, mapping_in
|
||||
|
||||
def make_gamepad_spi_packet(gp_status_dict, gp_id, axes_info):
|
||||
current_protocol = usb4vc_ui.get_gamepad_protocol()
|
||||
if current_protocol['pid'] == PID_GENERIC_GAMEPORT_GAMEPAD and current_protocol['is_custom']:
|
||||
if current_protocol['pid'] == PID_GENERIC_GAMEPORT_GAMEPAD:
|
||||
return make_generic_gamepad_spi_packet(gp_status_dict, gp_id, axes_info, current_protocol)
|
||||
return list(nop_spi_msg_template), None, None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user