Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit 0ca8cec

Browse files
committed
Push release code, hotfix for custom cameras
Updated repository to buildable version with costura.fody (for embedded dependencies) Fixed an issue where the user would be alerted about a "missing" discord webhook url, even if discord sync was disabled. Added CustomCamera and CustomCameraUrl to config to allow support of other mpeg-stream based cameras until proper integration is complete
1 parent acac32a commit 0ca8cec

11 files changed

Lines changed: 221 additions & 6 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ bin/
22
obj/
33
packages/
44
*.sln.DotSettings.user
5-
.idea/
5+
.idea/
6+
Folder.DotSettings.user

FlashForgeUI.csproj

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="packages\Costura.Fody.6.0.0\build\Costura.Fody.props" Condition="Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.props')" />
34
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
45
<PropertyGroup>
56
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -45,6 +46,9 @@
4546
<Reference Include="AForge.Video, Version=2.2.5.0, Culture=neutral, PublicKeyToken=cbfb6e07d173c401, processorArchitecture=MSIL">
4647
<HintPath>packages\AForge.Video.2.2.5\lib\AForge.Video.dll</HintPath>
4748
</Reference>
49+
<Reference Include="Costura, Version=6.0.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
50+
<HintPath>packages\Costura.Fody.6.0.0\lib\netstandard2.0\Costura.dll</HintPath>
51+
</Reference>
4852
<Reference Include="Discord Webhook, Version=1.0.9.0, Culture=neutral, PublicKeyToken=2620cdc36f88a594, processorArchitecture=MSIL">
4953
<HintPath>packages\Discord.Webhook.1.0.9\lib\netstandard2.0\Discord Webhook.dll</HintPath>
5054
</Reference>
@@ -190,6 +194,7 @@
190194
<None Include="App.config" />
191195
</ItemGroup>
192196
<ItemGroup>
197+
<Content Include="FodyWeavers.xml" />
193198
<Content Include="webui\wwwroot\**\*">
194199
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
195200
</Content>
@@ -200,4 +205,14 @@
200205
<Content Include="webui\wwwroot\js\script.js" />
201206
</ItemGroup>
202207
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
208+
<Import Project="packages\Fody.6.9.1\build\Fody.targets" Condition="Exists('packages\Fody.6.9.1\build\Fody.targets')" />
209+
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
210+
<PropertyGroup>
211+
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.</ErrorText>
212+
</PropertyGroup>
213+
<Error Condition="!Exists('packages\Fody.6.9.1\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Fody.6.9.1\build\Fody.targets'))" />
214+
<Error Condition="!Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.6.0.0\build\Costura.Fody.props'))" />
215+
<Error Condition="!Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.6.0.0\build\Costura.Fody.targets'))" />
216+
</Target>
217+
<Import Project="packages\Costura.Fody.6.0.0\build\Costura.Fody.targets" Condition="Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.targets')" />
203218
</Project>

FodyWeavers.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
3+
<Costura />
4+
</Weavers>

FodyWeavers.xsd

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3+
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
4+
<xs:element name="Weavers">
5+
<xs:complexType>
6+
<xs:all>
7+
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
8+
<xs:complexType>
9+
<xs:all>
10+
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
11+
<xs:annotation>
12+
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
13+
</xs:annotation>
14+
</xs:element>
15+
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
16+
<xs:annotation>
17+
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
18+
</xs:annotation>
19+
</xs:element>
20+
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
21+
<xs:annotation>
22+
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
23+
</xs:annotation>
24+
</xs:element>
25+
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
26+
<xs:annotation>
27+
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
28+
</xs:annotation>
29+
</xs:element>
30+
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
31+
<xs:annotation>
32+
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
33+
</xs:annotation>
34+
</xs:element>
35+
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX86Assemblies" type="xs:string">
36+
<xs:annotation>
37+
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with line breaks.</xs:documentation>
38+
</xs:annotation>
39+
</xs:element>
40+
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
41+
<xs:annotation>
42+
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead.</xs:documentation>
43+
</xs:annotation>
44+
</xs:element>
45+
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX64Assemblies" type="xs:string">
46+
<xs:annotation>
47+
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
48+
</xs:annotation>
49+
</xs:element>
50+
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinArm64Assemblies" type="xs:string">
51+
<xs:annotation>
52+
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
53+
</xs:annotation>
54+
</xs:element>
55+
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
56+
<xs:annotation>
57+
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
58+
</xs:annotation>
59+
</xs:element>
60+
</xs:all>
61+
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
62+
<xs:annotation>
63+
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
64+
</xs:annotation>
65+
</xs:attribute>
66+
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
67+
<xs:annotation>
68+
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
69+
</xs:annotation>
70+
</xs:attribute>
71+
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
72+
<xs:annotation>
73+
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
74+
</xs:annotation>
75+
</xs:attribute>
76+
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
77+
<xs:annotation>
78+
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
79+
</xs:annotation>
80+
</xs:attribute>
81+
<xs:attribute name="DisableCompression" type="xs:boolean">
82+
<xs:annotation>
83+
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
84+
</xs:annotation>
85+
</xs:attribute>
86+
<xs:attribute name="DisableCleanup" type="xs:boolean">
87+
<xs:annotation>
88+
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
89+
</xs:annotation>
90+
</xs:attribute>
91+
<xs:attribute name="DisableEventSubscription" type="xs:boolean">
92+
<xs:annotation>
93+
<xs:documentation>The attach method no longer subscribes to the `AppDomain.AssemblyResolve` (.NET 4.x) and `AssemblyLoadContext.Resolving` (.NET 6.0+) events.</xs:documentation>
94+
</xs:annotation>
95+
</xs:attribute>
96+
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
97+
<xs:annotation>
98+
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
99+
</xs:annotation>
100+
</xs:attribute>
101+
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
102+
<xs:annotation>
103+
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
104+
</xs:annotation>
105+
</xs:attribute>
106+
<xs:attribute name="ExcludeAssemblies" type="xs:string">
107+
<xs:annotation>
108+
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
109+
</xs:annotation>
110+
</xs:attribute>
111+
<xs:attribute name="IncludeAssemblies" type="xs:string">
112+
<xs:annotation>
113+
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
114+
</xs:annotation>
115+
</xs:attribute>
116+
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
117+
<xs:annotation>
118+
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
119+
</xs:annotation>
120+
</xs:attribute>
121+
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
122+
<xs:annotation>
123+
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
124+
</xs:annotation>
125+
</xs:attribute>
126+
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
127+
<xs:annotation>
128+
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
129+
</xs:annotation>
130+
</xs:attribute>
131+
<xs:attribute name="UnmanagedWinX86Assemblies" type="xs:string">
132+
<xs:annotation>
133+
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with |.</xs:documentation>
134+
</xs:annotation>
135+
</xs:attribute>
136+
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
137+
<xs:annotation>
138+
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead</xs:documentation>
139+
</xs:annotation>
140+
</xs:attribute>
141+
<xs:attribute name="UnmanagedWinX64Assemblies" type="xs:string">
142+
<xs:annotation>
143+
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
144+
</xs:annotation>
145+
</xs:attribute>
146+
<xs:attribute name="UnmanagedWinArm64Assemblies" type="xs:string">
147+
<xs:annotation>
148+
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
149+
</xs:annotation>
150+
</xs:attribute>
151+
<xs:attribute name="PreloadOrder" type="xs:string">
152+
<xs:annotation>
153+
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
154+
</xs:annotation>
155+
</xs:attribute>
156+
</xs:complexType>
157+
</xs:element>
158+
</xs:all>
159+
<xs:attribute name="VerifyAssembly" type="xs:boolean">
160+
<xs:annotation>
161+
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
162+
</xs:annotation>
163+
</xs:attribute>
164+
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
165+
<xs:annotation>
166+
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
167+
</xs:annotation>
168+
</xs:attribute>
169+
<xs:attribute name="GenerateXsd" type="xs:boolean">
170+
<xs:annotation>
171+
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
172+
</xs:annotation>
173+
</xs:attribute>
174+
</xs:complexType>
175+
</xs:element>
176+
</xs:schema>

packages.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
<package id="AForge.Imaging" version="2.2.5" targetFramework="net48" />
55
<package id="AForge.Math" version="2.2.5" targetFramework="net48" />
66
<package id="AForge.Video" version="2.2.5" targetFramework="net48" />
7+
<package id="Costura.Fody" version="6.0.0" targetFramework="net48" developmentDependency="true" />
78
<package id="Discord.Webhook" version="1.0.9" targetFramework="net48" />
9+
<package id="Fody" version="6.9.1" targetFramework="net48" developmentDependency="true" />
810
<package id="HttpMultipartParser" version="8.4.0" targetFramework="net48" />
911
<package id="Microsoft.IO.RecyclableMemoryStream" version="3.0.0" targetFramework="net48" />
1012
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />

program/util/Config.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ public class Config
1212
public bool DiscordSync { get; set; }
1313
public string WebhookUrl { get; set; }
1414

15+
public bool CustomCamera { get; set; }
16+
public string CustomCameraUrl { get; set; }
17+
1518

1619
private const string FilePath = "config.json";
1720

@@ -29,6 +32,8 @@ public Config Load()
2932
WebUi = false;
3033
DiscordSync = false;
3134
WebhookUrl = "";
35+
CustomCamera = false;
36+
CustomCameraUrl = "";
3237
Save();
3338
return this;
3439
}

ui/main/MainMenu.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ internal async void MainMenu_Shown(object sender, EventArgs e)
338338

339339
CheckFeatures();
340340

341-
InitWebhook();
341+
if (config.DiscordSync) InitWebhook(); // only check/enable the webhook if the user actually enabled it.
342342
await StartTimers();
343343
if (config.WebUi) StartWebUi();
344344
}

ui/main/manager/ButtonManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ public async Task LedOff()
3333
public void TogglePreview()
3434
{
3535
if (_ui.printerClient == null) return;
36-
if (!_ui.printerClient.IsPro)
37-
{ // make sure there's actually a webcam
36+
if (!_ui.printerClient.IsPro && !_ui.config.CustomCamera) // check for webcam or custom setup
37+
{
3838
MessageBox.Show("No webcam!",
3939
"The regular 5M has no built-in webcam. If you've installed one yourself, you can disable this check in settings");
4040
return;

ui/main/manager/MjpegStreamManager.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Drawing;
1+
using System;
2+
using System.Drawing;
23
using System.Threading.Tasks;
34
using System.Windows.Forms;
45
using AForge.Video;
@@ -17,7 +18,14 @@ public MjpegStreamManager(MainMenu form1)
1718

1819
public void Start()
1920
{
20-
_ui.mjpegStream = new MJPEGStream($"http://{_ui.printerClient.IpAddress}:8080/?action=stream");
21+
if (_ui.config.CustomCamera) // check for custom camera url
22+
{
23+
// allow users to use placeholders for the IP
24+
var url = _ui.config.CustomCameraUrl.Replace("{IpAddress}", _ui.printerClient.IpAddress);
25+
_ui.mjpegStream = new MJPEGStream(url);
26+
Console.WriteLine("Using custom camera url: " + url);
27+
}
28+
else _ui.mjpegStream = new MJPEGStream($"http://{_ui.printerClient.IpAddress}:8080/?action=stream"); // default for the 5M pro
2129
_ui.mjpegStream.NewFrame += MJPEGStream_NewFrame;
2230
_ui.mjpegStream.VideoSourceError += MJPEGStream_VideoSourceError;
2331
_ui.mjpegStream.Start();

ui/main/manager/StatusTimerManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,10 @@ private void SetJobComplete(FiveMClient.MachineInfo machineInfo)
108108

109109
private void SetEtaAndJobControls(FiveMClient.MachineInfo machineInfo)
110110
{
111+
// todo this needs to be refactored to use MachineState
111112
switch (machineInfo.Status)
112113
{
114+
case "cancel":
113115
case "completed":
114116
SetJobComplete(machineInfo); // update UI
115117
SetActiveJobControls(true); // show controls hidden during printing (will prompt to clear the bed first if not)

0 commit comments

Comments
 (0)