mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-11-29 20:44:20 +01:00
Minor optimization for device refreshing and profile switching
This commit is contained in:
parent
2cfaee50e5
commit
83c7bb7740
@ -316,7 +316,7 @@ namespace DS4Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerStatusChanged(this);
|
//ControllerStatusChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -394,7 +394,7 @@ namespace DS4Windows
|
|||||||
battery = Properties.Resources.Battery.Replace("*number*", d.getBattery().ToString());
|
battery = Properties.Resources.Battery.Replace("*number*", d.getBattery().ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return d.getMacAddress() + " (" + d.ConnectionType + "), " + battery;
|
return d.getMacAddress() + " (" + d.getConnectionType() + "), " + battery;
|
||||||
//return d.MacAddress + " (" + d.ConnectionType + "), Battery is " + battery + ", Touchpad in " + modeSwitcher[index].ToString();
|
//return d.MacAddress + " (" + d.ConnectionType + "), Battery is " + battery + ", Touchpad in " + modeSwitcher[index].ToString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -585,6 +585,12 @@ namespace DS4Windows
|
|||||||
//ControllerStatusChanged(this);
|
//ControllerStatusChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!device.firstReport && device.IsAlive())
|
||||||
|
{
|
||||||
|
device.firstReport = true;
|
||||||
|
OnDeviceStatusChanged(this, ind);
|
||||||
|
}
|
||||||
|
|
||||||
if (getEnableTouchToggle(ind))
|
if (getEnableTouchToggle(ind))
|
||||||
{
|
{
|
||||||
CheckForTouchToggle(ind, cState, pState);
|
CheckForTouchToggle(ind, cState, pState);
|
||||||
|
@ -179,6 +179,21 @@ namespace DS4Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DeviceStatusChangeEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public DeviceStatusChangeEventArgs(int index)
|
||||||
|
{
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex()
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class MultiValueDict<Key, Value> : Dictionary<Key, List<Value>>
|
public class MultiValueDict<Key, Value> : Dictionary<Key, List<Value>>
|
||||||
{
|
{
|
||||||
public void Add(Key key, Value val)
|
public void Add(Key key, Value val)
|
||||||
@ -271,7 +286,17 @@ namespace DS4Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//general values
|
public static event EventHandler<DeviceStatusChangeEventArgs> DeviceStatusChange;
|
||||||
|
public static void OnDeviceStatusChanged(object sender, int index)
|
||||||
|
{
|
||||||
|
if (DeviceStatusChange != null)
|
||||||
|
{
|
||||||
|
DeviceStatusChangeEventArgs args = new DeviceStatusChangeEventArgs(index);
|
||||||
|
DeviceStatusChange(sender, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// general values
|
||||||
public static bool UseExclusiveMode
|
public static bool UseExclusiveMode
|
||||||
{
|
{
|
||||||
set { m_Config.useExclusiveMode = value; }
|
set { m_Config.useExclusiveMode = value; }
|
||||||
@ -376,7 +401,7 @@ namespace DS4Windows
|
|||||||
get { return m_Config.useWhiteIcon; }
|
get { return m_Config.useWhiteIcon; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//controller/profile specfic values
|
// controller/profile specfic values
|
||||||
public static int[] ButtonMouseSensitivity => m_Config.buttonMouseSensitivity;
|
public static int[] ButtonMouseSensitivity => m_Config.buttonMouseSensitivity;
|
||||||
public static byte[] RumbleBoost => m_Config.rumble;
|
public static byte[] RumbleBoost => m_Config.rumble;
|
||||||
public static byte getRumbleBoost(int index)
|
public static byte getRumbleBoost(int index)
|
||||||
|
@ -27,6 +27,7 @@ namespace DS4Windows
|
|||||||
delegate void NotificationDelegate(object sender, DebugEventArgs args);
|
delegate void NotificationDelegate(object sender, DebugEventArgs args);
|
||||||
delegate void BatteryStatusDelegate(object sender, BatteryReportArgs args);
|
delegate void BatteryStatusDelegate(object sender, BatteryReportArgs args);
|
||||||
delegate void ControllerRemovedDelegate(object sender, ControllerRemovedArgs args);
|
delegate void ControllerRemovedDelegate(object sender, ControllerRemovedArgs args);
|
||||||
|
delegate void DeviceStatusChangedDelegate(object sender, DeviceStatusChangeEventArgs args);
|
||||||
protected Label[] Pads, Batteries;
|
protected Label[] Pads, Batteries;
|
||||||
protected ComboBox[] cbs;
|
protected ComboBox[] cbs;
|
||||||
protected Button[] ebns;
|
protected Button[] ebns;
|
||||||
@ -140,6 +141,7 @@ namespace DS4Windows
|
|||||||
firstrun = true;
|
firstrun = true;
|
||||||
new SaveWhere(false).ShowDialog();
|
new SaveWhere(false).ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstrun)
|
if (firstrun)
|
||||||
CheckDrivers();
|
CheckDrivers();
|
||||||
else
|
else
|
||||||
@ -154,6 +156,7 @@ namespace DS4Windows
|
|||||||
Close();
|
Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics g = this.CreateGraphics();
|
Graphics g = this.CreateGraphics();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -164,6 +167,9 @@ namespace DS4Windows
|
|||||||
{
|
{
|
||||||
g.Dispose();
|
g.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blankControllerTab();
|
||||||
|
|
||||||
Program.rootHub.Debug += On_Debug;
|
Program.rootHub.Debug += On_Debug;
|
||||||
|
|
||||||
Log.GuiLog += On_Debug;
|
Log.GuiLog += On_Debug;
|
||||||
@ -175,6 +181,7 @@ namespace DS4Windows
|
|||||||
Directory.CreateDirectory(appdatapath);
|
Directory.CreateDirectory(appdatapath);
|
||||||
Global.Load();
|
Global.Load();
|
||||||
if (!Save()) //if can't write to file
|
if (!Save()) //if can't write to file
|
||||||
|
{
|
||||||
if (MessageBox.Show("Cannot write at current location\nCopy Settings to appdata?", "DS4Windows",
|
if (MessageBox.Show("Cannot write at current location\nCopy Settings to appdata?", "DS4Windows",
|
||||||
MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
|
MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
|
||||||
{
|
{
|
||||||
@ -202,12 +209,15 @@ namespace DS4Windows
|
|||||||
Close();
|
Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//MessageBox.Show(Environment.OSVersion.VersionString);
|
//MessageBox.Show(Environment.OSVersion.VersionString);
|
||||||
cBUseWhiteIcon.Checked = UseWhiteIcon;
|
cBUseWhiteIcon.Checked = UseWhiteIcon;
|
||||||
Icon = Properties.Resources.DS4W;
|
Icon = Properties.Resources.DS4W;
|
||||||
notifyIcon1.Icon = UseWhiteIcon ? Properties.Resources.DS4W___White : Properties.Resources.DS4W;
|
notifyIcon1.Icon = UseWhiteIcon ? Properties.Resources.DS4W___White : Properties.Resources.DS4W;
|
||||||
foreach (ToolStripMenuItem t in shortcuts)
|
foreach (ToolStripMenuItem t in shortcuts)
|
||||||
t.DropDownItemClicked += Profile_Changed_Menu;
|
t.DropDownItemClicked += Profile_Changed_Menu;
|
||||||
|
|
||||||
hideDS4CheckBox.CheckedChanged -= hideDS4CheckBox_CheckedChanged;
|
hideDS4CheckBox.CheckedChanged -= hideDS4CheckBox_CheckedChanged;
|
||||||
hideDS4CheckBox.Checked = UseExclusiveMode;
|
hideDS4CheckBox.Checked = UseExclusiveMode;
|
||||||
hideDS4CheckBox.CheckedChanged += hideDS4CheckBox_CheckedChanged;
|
hideDS4CheckBox.CheckedChanged += hideDS4CheckBox_CheckedChanged;
|
||||||
@ -219,6 +229,7 @@ namespace DS4Windows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
btnConnectDS4Win10.Visible = false;
|
btnConnectDS4Win10.Visible = false;
|
||||||
|
|
||||||
cBDisconnectBT.Checked = DCBTatStop;
|
cBDisconnectBT.Checked = DCBTatStop;
|
||||||
cBQuickCharge.Checked = QuickCharge;
|
cBQuickCharge.Checked = QuickCharge;
|
||||||
nUDXIPorts.Value = FirstXinputPort;
|
nUDXIPorts.Value = FirstXinputPort;
|
||||||
@ -233,6 +244,7 @@ namespace DS4Windows
|
|||||||
string lang = CultureInfo.CurrentCulture.ToString();
|
string lang = CultureInfo.CurrentCulture.ToString();
|
||||||
if (lang.StartsWith("en"))
|
if (lang.StartsWith("en"))
|
||||||
cBDownloadLangauge.Visible = false;
|
cBDownloadLangauge.Visible = false;
|
||||||
|
|
||||||
cBDownloadLangauge.Checked = DownloadLang;
|
cBDownloadLangauge.Checked = DownloadLang;
|
||||||
cBFlashWhenLate.Checked = FlashWhenLate;
|
cBFlashWhenLate.Checked = FlashWhenLate;
|
||||||
nUDLatency.Value = FlashWhenLateAt;
|
nUDLatency.Value = FlashWhenLateAt;
|
||||||
@ -266,6 +278,7 @@ namespace DS4Windows
|
|||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start = true;
|
bool start = true;
|
||||||
bool mini = false;
|
bool mini = false;
|
||||||
for (int i = 0, argslen = arguements.Length; i < argslen; i++)
|
for (int i = 0, argslen = arguements.Length; i < argslen; i++)
|
||||||
@ -277,11 +290,13 @@ namespace DS4Windows
|
|||||||
if (mini && start)
|
if (mini && start)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(startMinimizedCheckBox.Checked || mini))
|
if (!(startMinimizedCheckBox.Checked || mini))
|
||||||
{
|
{
|
||||||
mAllowVisible = true;
|
mAllowVisible = true;
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
Form_Resize(null, null);
|
Form_Resize(null, null);
|
||||||
RefreshProfiles();
|
RefreshProfiles();
|
||||||
opt = new Options(this);
|
opt = new Options(this);
|
||||||
@ -300,10 +315,12 @@ namespace DS4Windows
|
|||||||
else
|
else
|
||||||
lights[i].BackColor = MainColor[i].ToColorA;
|
lights[i].BackColor = MainColor[i].ToColorA;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadP();
|
LoadP();
|
||||||
Global.ControllerStatusChange += ControllerStatusChange;
|
Global.ControllerStatusChange += ControllerStatusChange;
|
||||||
Global.BatteryStatusChange += BatteryStatusUpdate;
|
Global.BatteryStatusChange += BatteryStatusUpdate;
|
||||||
Global.ControllerRemoved += ControllerRemovedChange;
|
Global.ControllerRemoved += ControllerRemovedChange;
|
||||||
|
Global.DeviceStatusChange += DeviceStatusChanged;
|
||||||
Enable_Controls(0, false);
|
Enable_Controls(0, false);
|
||||||
Enable_Controls(1, false);
|
Enable_Controls(1, false);
|
||||||
Enable_Controls(2, false);
|
Enable_Controls(2, false);
|
||||||
@ -311,9 +328,11 @@ namespace DS4Windows
|
|||||||
btnStartStop.Text = Properties.Resources.StartText;
|
btnStartStop.Text = Properties.Resources.StartText;
|
||||||
if (btnStartStop.Enabled && start)
|
if (btnStartStop.Enabled && start)
|
||||||
btnStartStop_Clicked();
|
btnStartStop_Clicked();
|
||||||
|
|
||||||
startToolStripMenuItem.Text = btnStartStop.Text;
|
startToolStripMenuItem.Text = btnStartStop.Text;
|
||||||
if (!tLPControllers.Visible)
|
if (!tLPControllers.Visible)
|
||||||
tabMain.SelectedIndex = 1;
|
tabMain.SelectedIndex = 1;
|
||||||
|
|
||||||
//cBNotifications.Checked = Notifications;
|
//cBNotifications.Checked = Notifications;
|
||||||
cBoxNotifications.SelectedIndex = Notifications;
|
cBoxNotifications.SelectedIndex = Notifications;
|
||||||
cBSwipeProfiles.Checked = SwipeProfiles;
|
cBSwipeProfiles.Checked = SwipeProfiles;
|
||||||
@ -332,7 +351,6 @@ namespace DS4Windows
|
|||||||
|
|
||||||
Uri url = new Uri("http://23.236.26.40/ds4windows/files/builds/newest.txt"); //Sorry other devs, gonna have to find your own server
|
Uri url = new Uri("http://23.236.26.40/ds4windows/files/builds/newest.txt"); //Sorry other devs, gonna have to find your own server
|
||||||
|
|
||||||
|
|
||||||
if (checkwhen > 0 && DateTime.Now >= LastChecked + TimeSpan.FromHours(checkwhen))
|
if (checkwhen > 0 && DateTime.Now >= LastChecked + TimeSpan.FromHours(checkwhen))
|
||||||
{
|
{
|
||||||
wc.DownloadFileAsync(url, appdatapath + "\\version.txt");
|
wc.DownloadFileAsync(url, appdatapath + "\\version.txt");
|
||||||
@ -345,6 +363,7 @@ namespace DS4Windows
|
|||||||
System.Threading.Thread.Sleep(2000);
|
System.Threading.Thread.Sleep(2000);
|
||||||
File.Delete(exepath + "\\Updater.exe");
|
File.Delete(exepath + "\\Updater.exe");
|
||||||
}
|
}
|
||||||
|
|
||||||
//test.Start();
|
//test.Start();
|
||||||
hotkeysTimer.Start();
|
hotkeysTimer.Start();
|
||||||
hotkeysTimer.Tick += Hotkeys;
|
hotkeysTimer.Tick += Hotkeys;
|
||||||
@ -390,6 +409,27 @@ namespace DS4Windows
|
|||||||
this.StartWindowsCheckBox.CheckedChanged += new System.EventHandler(this.StartWindowsCheckBox_CheckedChanged);
|
this.StartWindowsCheckBox.CheckedChanged += new System.EventHandler(this.StartWindowsCheckBox_CheckedChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void blankControllerTab()
|
||||||
|
{
|
||||||
|
bool nocontrollers = true;
|
||||||
|
for (Int32 Index = 0, PadsLen = Pads.Length; Index < PadsLen; Index++)
|
||||||
|
{
|
||||||
|
// Make sure a controller exists
|
||||||
|
if (Index < ControlService.DS4_CONTROLLER_COUNT)
|
||||||
|
{
|
||||||
|
Pads[Index].Text = "";
|
||||||
|
|
||||||
|
statPB[Index].Visible = false; toolTip1.SetToolTip(statPB[Index], "");
|
||||||
|
Batteries[Index].Text = Properties.Resources.NA;
|
||||||
|
Pads[Index].Text = Properties.Resources.Disconnected;
|
||||||
|
Enable_Controls(Index, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lbNoControllers.Visible = nocontrollers;
|
||||||
|
tLPControllers.Visible = !nocontrollers;
|
||||||
|
}
|
||||||
|
|
||||||
private async void UpdateTheUpdater()
|
private async void UpdateTheUpdater()
|
||||||
{
|
{
|
||||||
if (File.Exists(exepath + "\\Update Files\\DS4Updater.exe"))
|
if (File.Exists(exepath + "\\Update Files\\DS4Updater.exe"))
|
||||||
@ -945,6 +985,75 @@ namespace DS4Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void DeviceStatusChanged(object sender, DeviceStatusChangeEventArgs args)
|
||||||
|
{
|
||||||
|
if (this.InvokeRequired)
|
||||||
|
{
|
||||||
|
DeviceStatusChangedDelegate d = new DeviceStatusChangedDelegate(DeviceStatusChanged);
|
||||||
|
this.BeginInvoke(d, new object[] { sender, args });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool nocontrollers = true;
|
||||||
|
for (int i = 0, arlen = Program.rootHub.DS4Controllers.Length; nocontrollers && i < arlen; i++)
|
||||||
|
{
|
||||||
|
DS4Device dev = Program.rootHub.DS4Controllers[i];
|
||||||
|
if (dev != null)
|
||||||
|
{
|
||||||
|
nocontrollers = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string tooltip = "DS4Windows v" + FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
|
||||||
|
int Index = args.getIndex();
|
||||||
|
if (Index >= 0 && Index < ControlService.DS4_CONTROLLER_COUNT)
|
||||||
|
{
|
||||||
|
Pads[Index].Text = Program.rootHub.getDS4MacAddress(Index);
|
||||||
|
|
||||||
|
switch (Program.rootHub.getDS4Status(Index))
|
||||||
|
{
|
||||||
|
case "USB": statPB[Index].Visible = true; statPB[Index].Image = Properties.Resources.USB; toolTip1.SetToolTip(statPB[Index], ""); break;
|
||||||
|
case "BT": statPB[Index].Visible = true; statPB[Index].Image = Properties.Resources.BT; toolTip1.SetToolTip(statPB[Index], "Right click to disconnect"); break;
|
||||||
|
case "SONYWA": statPB[Index].Visible = true; statPB[Index].Image = Properties.Resources.BT; toolTip1.SetToolTip(statPB[Index], "Right click to disconnect"); break;
|
||||||
|
default: statPB[Index].Visible = false; toolTip1.SetToolTip(statPB[Index], ""); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Batteries[Index].Text = Program.rootHub.getDS4Battery(Index);
|
||||||
|
if (Pads[Index].Text != String.Empty)
|
||||||
|
{
|
||||||
|
if (runningBat)
|
||||||
|
{
|
||||||
|
SendKeys.Send("A");
|
||||||
|
runningBat = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pads[Index].Enabled = true;
|
||||||
|
if (Pads[Index].Text != Properties.Resources.Connecting)
|
||||||
|
{
|
||||||
|
Enable_Controls(Index, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
opt.inputtimer.Stop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pads[Index].Text = Properties.Resources.Disconnected;
|
||||||
|
Enable_Controls(Index, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Program.rootHub.getShortDS4ControllerInfo(Index) != Properties.Resources.NoneText)
|
||||||
|
tooltip += "\n" + (Index + 1) + ": " + Program.rootHub.getShortDS4ControllerInfo(Index); // Carefully stay under the 63 character limit.
|
||||||
|
}
|
||||||
|
|
||||||
|
lbNoControllers.Visible = nocontrollers;
|
||||||
|
tLPControllers.Visible = !nocontrollers;
|
||||||
|
if (tooltip.Length > 63)
|
||||||
|
notifyIcon1.Text = tooltip.Substring(0, 63);
|
||||||
|
else
|
||||||
|
notifyIcon1.Text = tooltip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void ControllerRemovedChange(object sender, ControllerRemovedArgs args)
|
protected void ControllerRemovedChange(object sender, ControllerRemovedArgs args)
|
||||||
{
|
{
|
||||||
if (this.InvokeRequired)
|
if (this.InvokeRequired)
|
||||||
@ -1358,7 +1467,8 @@ namespace DS4Windows
|
|||||||
ebns[tdevice].Text = Properties.Resources.EditProfile;
|
ebns[tdevice].Text = Properties.Resources.EditProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerStatusChanged(); //to update profile name in notify icon
|
OnDeviceStatusChanged(this, tdevice); //to update profile name in notify icon
|
||||||
|
//ControllerStatusChanged(); //to update profile name in notify icon
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Profile_Changed_Menu(object sender, ToolStripItemClickedEventArgs e)
|
private void Profile_Changed_Menu(object sender, ToolStripItemClickedEventArgs e)
|
||||||
|
@ -115,7 +115,7 @@ namespace DS4Windows
|
|||||||
return RumbleMotorsExplicitlyOff || RumbleMotorStrengthLeftHeavySlow != 0 || RumbleMotorStrengthRightLightFast != 0;
|
return RumbleMotorsExplicitlyOff || RumbleMotorStrengthLeftHeavySlow != 0 || RumbleMotorStrengthRightLightFast != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DS4Device
|
public class DS4Device
|
||||||
{
|
{
|
||||||
private const int BT_OUTPUT_REPORT_LENGTH = 78;
|
private const int BT_OUTPUT_REPORT_LENGTH = 78;
|
||||||
@ -530,6 +530,7 @@ namespace DS4Windows
|
|||||||
private byte priorInputReport30 = 0xff;
|
private byte priorInputReport30 = 0xff;
|
||||||
public double Latency = 0;
|
public double Latency = 0;
|
||||||
public string error;
|
public string error;
|
||||||
|
public bool firstReport = false;
|
||||||
|
|
||||||
private void performDs4Input()
|
private void performDs4Input()
|
||||||
{
|
{
|
||||||
@ -820,6 +821,7 @@ namespace DS4Windows
|
|||||||
bool output = false;
|
bool output = false;
|
||||||
for (int i = 0, arlen = outputReport.Length; !output && i < arlen; i++)
|
for (int i = 0, arlen = outputReport.Length; !output && i < arlen; i++)
|
||||||
output = outputReport[i] != outputReportBuffer[i];
|
output = outputReport[i] != outputReportBuffer[i];
|
||||||
|
|
||||||
if (output)
|
if (output)
|
||||||
{
|
{
|
||||||
outputRumble = true;
|
outputRumble = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user