-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[REFERENCE] hotfix for new Legion Space update v1.0.2.5: Controller READY-byte an… #892
Changes from all commits
1e3007b
0d514cb
da79fbb
70983fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -42,6 +42,10 @@ private enum BackEnum | |||||||
private const byte BACK_IDX = 19; | ||||||||
private const byte STATUS_IDX = 0; | ||||||||
private const byte PING_IDX = 40; | ||||||||
private HashSet<int> READY_STATES = new HashSet<int>() {25, 60}; | ||||||||
|
||||||||
private const byte MIN_WIRELESS_STATUS = 40; | ||||||||
private const byte MAX_WIRELESS_STATUS = 50; | ||||||||
|
||||||||
private Thread dataThread; | ||||||||
private bool dataThreadRunning; | ||||||||
|
@@ -52,16 +56,16 @@ public override bool IsReady | |||||||
get | ||||||||
{ | ||||||||
byte status = GetStatus(STATUS_IDX); | ||||||||
return status == 25; | ||||||||
return READY_STATES.Contains(status); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
Valkirie marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
public bool IsWireless | ||||||||
{ | ||||||||
get | ||||||||
Comment on lines
63
to
65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate property definition. - public bool IsWireless
- {
- get Committable suggestion
Suggested change
|
||||||||
{ | ||||||||
byte status = GetStatus(PING_IDX); | ||||||||
return (status >= 40 && status <= 50); | ||||||||
byte status = GetStatus(PING_IDX); | ||||||||
return (status >= MIN_WIRELESS_STATUS && status <= MAX_WIRELESS_STATUS); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
|
@@ -235,11 +239,12 @@ private async void dataThreadLoop(object? obj) | |||||||
if (hidDevice is null) | ||||||||
continue; | ||||||||
|
||||||||
HidReport report = hidDevice.ReadReport(); | ||||||||
HidReport report = hidDevice.ReadReport(); | ||||||||
|
||||||||
if (report is not null) | ||||||||
Valkirie marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
{ | ||||||||
// check if packet is safe | ||||||||
if (report.Data[STATUS_IDX] == 25) | ||||||||
if (READY_STATES.Contains(report.Data[STATUS_IDX])) | ||||||||
Data = report.Data; | ||||||||
} | ||||||||
Comment on lines
+242
to
249
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The search results show multiple accesses to the Given that the This could potentially lead to race conditions where one thread is writing to the Based on the information provided, it is reasonable to conclude that the
Analysis chainThe Scripts ExecutedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Check for any other occurrences of 'Data' being accessed without proper synchronization.
rg --type cs "Data" --context 5 HandheldCompanion/Controllers/LegionController.cs
Length of output: 3585 |
||||||||
} | ||||||||
|
@@ -370,17 +375,9 @@ public void HandleTouchpadInput(bool touched, ushort x, ushort y) | |||||||
|
||||||||
internal void SetPassthrough(bool enabled) | ||||||||
{ | ||||||||
switch(enabled) | ||||||||
{ | ||||||||
case true: | ||||||||
SetTouchPadStatus(1); | ||||||||
break; | ||||||||
case false: | ||||||||
SetTouchPadStatus(0); | ||||||||
break; | ||||||||
} | ||||||||
|
||||||||
SetTouchPadStatus(enabled ? 1 : 0); | ||||||||
IsPassthrough = enabled; | ||||||||
} | ||||||||
|
||||||||
} | ||||||||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,107 @@ | ||||||
using HandheldCompanion.Devices; | ||||||
using HandheldCompanion.Utils; | ||||||
using HandheldCompanion.Views; | ||||||
using System; | ||||||
using System.Collections.Generic; | ||||||
using System.Linq; | ||||||
using System.ServiceProcess; | ||||||
using System.Threading.Tasks; | ||||||
using System.Timers; | ||||||
using System.Windows; | ||||||
|
||||||
namespace HandheldCompanion.Controls.Hints | ||||||
{ | ||||||
public class Hint_LegionGoServices : IHint | ||||||
{ | ||||||
private List<string> serviceNames = new() | ||||||
{ | ||||||
"DAService", | ||||||
}; | ||||||
Comment on lines
+16
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider externalizing the service names to a configuration file or resource for easier maintenance. |
||||||
|
||||||
private List<ServiceController> serviceControllers = new(); | ||||||
private Timer serviceTimer; | ||||||
|
||||||
public Hint_LegionGoServices() : base() | ||||||
{ | ||||||
if (MainWindow.CurrentDevice is not LegionGo) | ||||||
return; | ||||||
|
||||||
// Get all the services installed on the local computer | ||||||
ServiceController[] services = ServiceController.GetServices(); | ||||||
foreach (string serviceName in serviceNames) | ||||||
{ | ||||||
if (services.Any(s => serviceNames.Contains(s.ServiceName))) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Logical error in service existence check. - if (services.Any(s => serviceNames.Contains(s.ServiceName)))
+ if (services.Any(s => s.ServiceName == serviceName)) Committable suggestion
Suggested change
|
||||||
{ | ||||||
// Create a service controller object for the specified service | ||||||
ServiceController serviceController = new ServiceController(serviceName); | ||||||
serviceControllers.Add(serviceController); | ||||||
} | ||||||
} | ||||||
|
||||||
// Check if any of the services in the list exist | ||||||
if (!serviceControllers.Any()) | ||||||
return; | ||||||
Comment on lines
+42
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider providing user feedback or logging when no services are found on the system. |
||||||
|
||||||
serviceTimer = new Timer(4000); | ||||||
serviceTimer.Elapsed += ServiceTimer_Elapsed; | ||||||
serviceTimer.Start(); | ||||||
|
||||||
// default state | ||||||
this.HintActionButton.Visibility = Visibility.Visible; | ||||||
|
||||||
this.HintTitle.Text = Properties.Resources.Hint_LegionGoServices; | ||||||
this.HintDescription.Text = Properties.Resources.Hint_LegionGoServicesDesc; | ||||||
this.HintReadMe.Text = Properties.Resources.Hint_LegionGoServicesReadme; | ||||||
|
||||||
this.HintActionButton.Content = Properties.Resources.Hint_LegionGoServicesAction; | ||||||
} | ||||||
|
||||||
private void ServiceTimer_Elapsed(object? sender, ElapsedEventArgs e) | ||||||
{ | ||||||
if(!serviceControllers.Any()) | ||||||
return; | ||||||
|
||||||
// Check if any of the services in the list exist and are running | ||||||
bool anyRunning = false; | ||||||
|
||||||
foreach (ServiceController serviceController in serviceControllers) | ||||||
{ | ||||||
serviceController.Refresh(); | ||||||
if (serviceController.Status == ServiceControllerStatus.Running) | ||||||
{ | ||||||
anyRunning = true; | ||||||
break; | ||||||
} | ||||||
} | ||||||
|
||||||
// UI thread (async) | ||||||
Application.Current.Dispatcher.BeginInvoke(() => | ||||||
{ | ||||||
this.Visibility = anyRunning ? Visibility.Visible : Visibility.Collapsed; | ||||||
}); | ||||||
} | ||||||
|
||||||
protected override void HintActionButton_Click(object sender, RoutedEventArgs e) | ||||||
{ | ||||||
if (!serviceControllers.Any()) | ||||||
return; | ||||||
|
||||||
Task.Run(async () => | ||||||
{ | ||||||
foreach (ServiceController serviceController in serviceControllers) | ||||||
{ | ||||||
if (serviceController.Status == ServiceControllerStatus.Running) | ||||||
serviceController.Stop(); | ||||||
serviceController.WaitForStatus(ServiceControllerStatus.Stopped); | ||||||
ServiceUtils.ChangeStartMode(serviceController, ServiceStartMode.Disabled, out _); | ||||||
} | ||||||
Valkirie marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
}); | ||||||
} | ||||||
|
||||||
public override void Stop() | ||||||
{ | ||||||
serviceTimer.Stop(); | ||||||
base.Stop(); | ||||||
} | ||||||
} | ||||||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the previous comment about making
READY_STATES
readonly and the absence of any code modifying it after initialization, it should be marked asreadonly
to prevent accidental modifications and clarify the intent.Committable suggestion