www.devsfordevs.com
Open in
urlscan Pro
2606:4700:3033::ac43:d1ac
Public Scan
Submitted URL: http://www.devsfordevs.com/
Effective URL: https://www.devsfordevs.com/
Submission: On August 22 via api from US — Scanned from US
Effective URL: https://www.devsfordevs.com/
Submission: On August 22 via api from US — Scanned from US
Form analysis
0 forms found in the DOMText Content
WHY NOT EAT SOME COOKIES? šŖ By clicking āAccept all cookiesā, you agree DevsForDevs can store cookies on your device and disclose information in accordance with our Cookie Policy. AcceptDeclineManage cookies Home About Donate Shop LoginSignup LATEST POSTS LatestTopFollowing @Christopher Bell Ā· Draft Ā· Aug 20, 2024 Ā· 5 min read Ā· 29 Views SUNSHINE/MOONLIGHT ADVANCED SETTINGS Hello I am back with an article on some advanced settings for Sunshine and better Moonlight bitrate targets. For setup of your system see my previous articles here on Devs4Devs. Self Hosted Cloud Gaming Part 1: https://www.devsfordevs.com/blogs/110-Sunshine%3A-Self-Hosted-Cloud-Gaming : Self Hosted Cloud Gaming Part 2: https://www.devsfordevs.com/blogs/111-Sunshine%3A-Self-Hosted-Cloud-Gaming-Part-2 I use Sunshine nearly daily and have been since shortly after it launched. I originally used it in my main gaming computer as my homelab urge grew stronger I converted this PC into a server. I still wanted to game so I used Sunshine/Moonlight and a headless monitor driver called IDDSampleDriver. To maximize performance especially at higher resolutions you may need to adjust some settings. For reference my system has been able to stream resolutions up to 4k30fps. I havenāt tested higher because my PC would melt. Most the settings are fairly explanatory some not so much. Hereās my best interpretation feel free to correct me if Iām wrong itās a learning experience. PC: Ryzen 7 3rd gen 8c16t RTX 3070ti 32GB assigned RAM The settings you will most likely want to adjust are under the āAdvancedā tab: FEC Percentage : This setting has a fairly sizable impact on overall streaming performance. It also has a sizable impact on overall network usage. By correcting for more packet loss we are able to get better image consistency and a more stable network. You should adjust this if you notice frame rate drops or noticeable input lag coming from the network. I was able to deduce this by using task manager to watch network throughput before during and after frame rate drops. At the same time as the FPS drop I would notice a drop in packets. Other times where it may be beneficial to increase this is when a device you use often has poor signal quality. This can lead to higher packet loss and increasing FEC percentage can help to correct this. I have only encountered this on my OLED Switch. My setting: 50 QP: 1 I donāt want a lot of compression and increasing this increases compression. If you have limited bandwidth then increase this. Minimum CPU Thread Count: Iām not sure how beneficial this was overall I donāt notice a high level of CPU cost for encoding thatās done with my GPU. I assigned half my available threads mostly because why not? AV1 Support: I leave this at the default I have no experience with AMD and Intel GPUs so this next section only applies to NVIDIA GPUs Under the Nvidia Encoder tab Performance Preset: This is s nifty little function if you increase the P# you will basically get the same result as increasing the bitrate. I canāt really exceed 200-250Mbps bitrate without network saturation so I generally leave this at P1 but I have had good results through P4 without too much latency or bandwidth increase. This does seem to increase overall quality when also increasing bitrate this is the most likely solution for 4k60+ to work. It will take a 2.5Gbps+ network a powerful PC and patience. Two-Pass Mode: I have set 2 pass mode to full resolution it seems to have more stability and has not significantly impacted overall network performance or encoding performance too badly. Spatial AQ: I keep this enabled because I stream on mobile networks while travelling I also stream to an OLED Switch. Generally I am streaming 720p when mobile and to the Switch. At maximum I set it to about 12Mbps this tends to be the maximum mobile networks in my area can handle given average connection speeds. Spatial AQ helps by increasing compression. At 720p any quality decrease is hardly noticeable and mostly results in texture blurring with more graphically demanding games. Single-frame VBV/HRD percentage increase: From what I understand this can increase the systems ability to adjust the bitrate but if your network has a lot of headroom you can increase this significantly. Iām running Wireless with a 1Gbps backhaul and 2.5Gbps ethernet to my server I have increased this to maximum and have had no issues running as high as 1440p 120hz. I do start to see network issues when running in the 4k60+ range. Use realtime priority in hardware accelerated gpu scheduling: I set this to disabled mostly because I stream at 1080p or less. This prevents my GPU from freezing when it is close to maximum load which provides more consistency. This could significantly affect the resolution you are able to steam at and should be enabled if you tend to stream at 1440p60 or higher. All other settings I keep at default. Moonlight settings These are my aproximate bitrate suggestions for your streaming. These may need to be adjusted depending on above settings and available bandwidth. 720p30/60: 8-14 Mbps 1080p60: 25-50Mbps 1440p120/144: 50-100Mbps 4k60: 125-150Mbps Changing settings can easily double the actual network bandwith you use bear this in mind based on your hardware and network resources. 0029 0 -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- Who-am-I? Ā· Draft Ā· Jun 21, 2024 Ā· 1 min read Ā· 97 Views A FUNNY WINDOWS MONITOR ! VISIBILITYCHANGE When the user left the web page you will find an interesting alter to complain to you: This is how to work to attract the user as a small and unpopular web app: window.addEventListener('visibilitychange' function() { if (document.visibilityState === "hidden") { //when you left the page alert('Cruel heartless you abandoned me alone! ā*: .ļ½”. o(ā§ā½ā¦)o .ļ½”.:*ā') }else if (document.visibilityState === "visible") { //when you went back the page console.log('Master! Welcome let me service to you ć¾(ā§ā½ā¦*)o'); } }); 0097 0 -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- Who-am-I? Ā· Draft Ā· Jun 11, 2024 Ā· 1 min read Ā· 70 Views SUPPORT ITALIC I made a tool. This tool can make many fonts without Italic font style support Italic font: from fontTools.ttLib import TTFont from fontTools.pens.transformPen import TransformPen from fontTools.pens.ttGlyphPen import TTGlyphPen def italicize_glyph(glyph italic_angle glyf_table): if glyph.isComposite(): for component in glyph.components: base_glyph = glyf_table[component.glyphName] italicized_base_glyph = italicize_glyph(base_glyph italic_angle glyf_table) glyf_table[component.glyphName] = italicized_base_glyph return glyph new_pen = TTGlyphPen(glyf_table) transform = (1 0 italic_angle 1 0 0) pen = TransformPen(new_pen transform) glyph.draw(pen glyf_table) return new_pen.glyph() def italicize_font(font_path italic_angle output_path): font = TTFont(font_path) glyf_table = font['glyf'] for glyph_name in font.getGlyphOrder(): glyph = glyf_table[glyph_name] if not glyph.isComposite(): italicized_glyph = italicize_glyph(glyph italic_angle glyf_table) glyf_table[glyph_name] = italicized_glyph if 'post' in font: font['post'].italicAngle = italic_angle * 180 / 3.14159 font.save(output_path) italic_angle = 0.3 input_font_path = "your/path/font-Normal.ttf" output_font_path = "your/path/font-Italic.ttf" italicize_font(input_font_path italic_angle output_font_path) 0070 0 -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- @0.361141050455305 Ā· Draft Ā· Apr 13, 2024 Ā· 1 min read Ā· 123 Views TEST nakashima 00123 1 -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- @Christopher Bell Ā· Draft Ā· Apr 7, 2024 Ā· 9 min read Ā· 797 Views SUNSHINE: SELF HOSTED CLOUD GAMING PART 2 This will be part 2 of my guide to a cloud gaming rig with remote access available from any device that supports Moonlight game streaming client. You can find the Sunshine installation article written by Ben Herbst here and you can find the Part 1 of my self hosted series here . If you are just starting out on this article I would encourage you to read these 2 articles first. This article will include fewer pictures and be more technical. This article will focus on virtualizing your machine and using a display driver software to emulate a monitor. Virtualizing your gaming machine has several benefits. Reduced power usage if you already run a 24/7 server/lab or the ability to add new services or self host services using the overhead your PC doesn't. Most gaming PCs have more RAM and CPU power than they need and sharing this with other services allows your equipment to pull double duty. It also provides the ability to easily access and maintain your PC from any computer with an internet connection. I will be using ProxMox VE (PVE) as a hypervisor and will explain creating the VM setting up GPU passthrough for an Nvidia GPU and installing the display driver with proper configuration. To install PVE download the ISO image here and install it through USB using Rufus Ventoy or your preferred installation media. Creating the Windows 11 VM Creating the Windows VM is pretty straightforward. Open a browser and navigate to your PVE GUI and login. Navigate to your "local" drive or any storage that allows ISO Images to be stored and downloaded. Choose the option for "ISO Images" and click the "Download from URL" button. Open a new browser tab and navigate to here . Follow the instructions in the section for download the disk image. When you get to the end right click the download link copy the link URL and past it in PVE. Once the ISO has finished downloading click the "Create VM" button in the top right of your PVE UI. Name your VM and check the "Advanced" option at the bottom of the window you should also check the box "Start at boot". Click "Next" and for OS mount the ISO image we downloaded earlier click "Next". The system settings should be as follows: Graphic Card: Default Machine: q35 BIOS: OVMF (UEFI) Add EFI Disk: Enabled EFI Storage: Choose a disk Pre-Enroll keys: Enabled SCSI Controller: VirtIO SCSI single QEMU Agent: Disabled Add TPM: Enabled TPM Storage: Choose a disk Click "Next" choose an installation disk in the drop down next to "Storage" then choose the amount of space you'd like to allocate the VM OS drive. If it's an SSD check the box for "SSD Emulation" if you use ProxMox Backup Server check tha "Backup" box then hit "Next". In CPU assign as many cores as you'd like for "Type" choose host then hit "Next". Under "Memory" assign at least 9GB of memory leave the. Leave "Network" default hit "Next" review the settings then click "Finish". Your VM will be created but we aren't quite done. Before we start the VM we need to add some CPU configurations type the following command: sudo nano /etc/pve/qemu-server/<you_vmid>.conf Edit the following lines to look like this: cpu: host hidden=1 flags=+pcid args: -cpu 'host +kvm_pv_unhalt +kvm_pv_eoi hv_vendor_id=NV43FIX kvm=off' CTL+X and save. Now you can boot the VM and go through the Windows 11 installation steps. When you have finished this shutdown the VM. Navigate to the VM's "Hardware" tab in PVE and add any storage media you would like. We will also add the GPU here but we need to complete a couple steps first. Passthrough a GPU to the VM There are several things we will need to do from the PVE CLI to enable GPU passthrough. If you're using Intel or AMD configure the Grub: sudo nano /etc/default/grub Look for the line: GRUB_CMDLINE_LINUX_DEFAULT="quiet" Then change it to look like this: Intel: GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on" AMD: GRUB_CMDLINE_LINUX_DEFAULT="quiet amd" It is also recommended to add extra commands to this line like so: GRUB_CMDLINE_LINUX_DEFAULT="quiet iommu=pt pcie_acs_override=downstream multifunction nofb nomodeset video=vesafb:off efifb:off" Here is some information on what these commands do: Disabling the Framebuffer ACS Override for IOMMU groups When you have finished editing Grub run CTL+X and save then run this command: update-grub Next you need to add some VFIO modules to PVE: sudo nano /etc/modules Add the following to the file: vfio vfio_iommu_type1 vfio_pci vfio_virqfd CTL+X and save the file. You will then run 2 commands: echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf echo "options kvm ignore_msrs=1" > /etc/modprobe.d/kvm.conf Next you will blacklist the host from using the drivers. WARNING: This will make it so that you can't manage the host from the GPU hardware echo "blacklist radeon" >> /etc/modprobe.d/blacklist.conf echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf echo "blacklist nvidia" >> /etc/modprobe.d/blacklist.conf Last command will be lspci -v This will display a lot of information about attached devices you are looking for something like: 01:00.0 VGA compatible controller: NVIDIA Corporation GA104 [GeForce RTX 3070 Ti] (rev a1) (prog-if 00 [VGA controller]) Then run the command replace the number with your GPU: lspci -n -s 01:00 This should output your GPU Vendor IDs one for the GPU and the other for Audio. It will look something like this: 01:00.0 0000: 10de:1b81 (rev a1) 01:00.1 0000: 10de:10f0 (rev a1) You will need these vendor ids in our next command: echo "options vfio-pci ids=10de:1b81 10de:10f0 disable_vga=1"> /etc/modprobe.d/vfio.conf Then you will run this command: update-initramfs -u And restart: reboot Now you should be ready to passthrough a GPU. Go back to the VM "Hardware" section and add a PCI device. Find your GPU from the dropdown and select it. On the options screen you should configure it like this: All Functions: Enabled Rom-Bar: Enabled Primary GPU: Disabled PCI-Express: Enabled Now start the Windows VM up and install Nvidia Geforce Experience or the appropriate Nvidia driver or your appropriate GPU driver(s). Refer to the first guide written by Ben Herbst to setup Sunshine and Moonlight. Next we will setup a display driver that will allow us to create a dummy monitor and access the machine headless. IDDSampleDriver and Headless To go headless we first need to create a dummy monitor. This will also allow us to specify a range of common resolutions for the dummy monitor. Some resolutions like mobile devices will still need to be added using CRU you can find the download link in part one of this guide. To setup the dummy display we need to download a display driver called IDDSampleDriver download it here . There are links to download an HDR version as well as a non-HDR version. If you have any HDR screens you will stream to download the HDR version. Take these note that you can edit the options.txt before installing the driver to add resolutions: Download the latest version and extract the contents to a folder. Copy option.txt to C:\IddSampleDriver\option.txt before installing the driver (important!) . Right click and run the *.bat file as an Administrator to add the driver certificate as a trusted root certificate. Don't install the inf. Open device manager click on any device then click on the "Action" menu and click "Add Legacy Hardware". Select "Add hardware from a list (Advanced)" and then select Display adapters Click "Have Disk..." and click the "Browse..." button. Navigate to the extracted files and select the inf file. You are done! Go to display settings to customize the resolution. Once you have installed the driver Windows will show 2 monitors one from PVE and one from the display driver. Now that we have Sunshine setup a Moonlight client connected and the dummy display driver attached we can disable the standard display driver. NOTE: Disabling this will remove the ability to access the VM from console or PVE. You will have to connect a monitor directly to the GPU and passthrough USB for access to the VM or use the Moonlight client. We now have a virtualized Windows PC with GPU passthrough enabled drivers installed and remote capability ready. If you encounter any errors leave a comment below and I can update this guide or write another article with troubleshooting and resolutions for common issues. My next article will focus on setting up Playnite creating save game backups and using it as your console style launcher. Once you have read these articles you will have a polished professional remote capable gaming setup with all the features and benefits you would expect from a high end gaming system. A Word on Security It is possible to have Moonlight accessible from the internet using the Moonlight Internet Hosting tool. I will not cover that here it requires exposing ports and in my opinion that is very dangerous . If you want to be able to access it outside your home network with that security risk the guide is available here . I would instead encourage you to use a VPN tunnel such as Wireguard Netmaker Tailscale or something similar. This will provide more security and some routers may support Wireguard directly. This eliminates the need for open ports except the single port for the VPN tunnel. There are many articles on setting up VPN tunnels a quick simple solution would be wg-easy found here . **I plan to update this article to include MonitorSwapAutomation and ResolutionAutomation for better monitor management. 30797 1 -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- @Christopher Bell Ā· Draft Ā· Apr 7, 2024 Ā· 10 min read Ā· 3492 Views SUNSHINE: SELF HOSTED CLOUD GAMING I recently read an article written by Ben Herbst here on DevsforDevs about setting up Sunshine as a Self-Hosted remote gaming service. It's a great article on getting the initial setup completed and adding your first PC client using Moonlight. I won't be reinventing the wheel so for the initial setup please read it here . Sunshine is a great service for remote gaming but it is also a fantastic low latency solution for VNC or RDP access to your machine. What I will be writing about will expand on Ben's article and I will review: Tips for setting up applications quickly and easily in Sunshine Tips on downloading box art and setting art in Sunshine so it appears in the Moonlight client Basic set up of Playnite as a unified launcher including a mobile interface that looks and works amazing on portable devices. How to change resolution using Sunshine to support mobile devices or hardware with non-standard resolutions Recommended settings for Moonlight depending on resolution and use case (portable or home) In a Part 2 article I will take this a step further and teach you how to completely virtualize your gaming rig. There are many benefits to a virtualized rig which I will discuss in the next article. After finishing both articles you should be able to go from a bare metal Windows gaming rig to a fully virtualized "cloud"-type setup. Post Sunshine Install: Setup and Tips After you've completed the initial Sunshine setup you will want to add applications setup box art and/or setup Playnite as a unified game launcher. Playnite has the added benefit of a really nice interface for mobile devices with a controller based GUI. Login to your Sunshine instance at localhost:47990 and at the top choose "Applications". When this section has loaded you will see a button to "Add New" click this button. It will load a form to fill out below your application list: Name the application leave "Output blank" and leave "Global Prep Commands' enabled. For now we will skip the "Command Preparations" section we will come back to this later. In the box labeled "Command" you will put the path to the game or application you want to launch. To simply launch your desktop leave the box empty. "Working Directory" is not required for most software. Scroll down a little further and you will see an empty box labeled "Image". This is where you will put box art that will appear in the Moonlight client. To add box art put the path to the image file. I use https://www.steamgriddb.com/ to download box art for games and software. SteamGrid DB box art has the proper size and resolution image for the majority of games and software I've needed. To quickly copy the location of software or images you can navigate to the item in Windows 11 right click on the exe or image and choose "copy as a path". Paste this link to the Command or Image box and remove the quotations that surround the directory path. Basic Playnite Setup This section of the article will cover the basic steps to get Playnite up and running and how to add it to Sunshine. This will not cover an in depth setup of Playnite such as add-ons game libraries or backups. You can refer to the Playnite documentation for additional configuration. Open a browser and navigate to https://playnite.link/ download the Playnite software and install it to your gaming rig. To make Playnite work as a unified launcher you will need to add your game libraries. To do this click the controller in the top left and choose "Add-ons" from the drop down menu. Browse will allow you to install add-on libraries for your game services. Once installed you configure the libraries in the "Extensions settings" section. Navigate to "Themes Fullscreen" in the "Browse" section. My preferred theme for mobile devices is "Playnite Modern UI". Now we can add Playnite to Sunshine so that we launch directly into our "console" mode or "Desktop" mode. Adding Playnite to Sunshine is done the same way as adding any other application. Start by navigating to your Playnite installation folder for me that's 'D:/Playnite' scroll down until you see 2 applications "Playnite.Desktop.App" and "Playnite.Fullscreen.App". Right click Playnite.Desktop.App and copy the location add it to Sunshine and name it Playnite. Do the same for Playnite.Fullscreen.App and name it Playnite Mobile. Next I will teach you how to change resolutions using scripts and commands in Sunshine. Sunshine Utils and Resolution Changes When I first started using Sunshine I didn't have a way to automatically change resolutions. Every time I would access my gaming rig from a different device I would manually change resolutions in Windows. I tried several different solutions and the easiest best option I found is a resolution change utility on Github called Sunshine-Utils. You can download it here . Create a folder on your PC and name it Sunshine-Utils. Download the resolution_change.exe and place in this folder. NOTE: The exe may trigger a warning from your anti-virus. I did a code review of the code and everything seemed in order. After discussion with the dev it's likely due to the language/compilation of the app since it's common for bad actors or those with limited coding skills. Feel free to review the code and if you are a software developer you may be able to contribute. Now we will need to create a script so that Sunshine can execute a resolution change. This is fairly simple create a text file in the same folder as the resolution_change.exe and enter: resolution_change.exe --width 1920 --height 1080 --refreshrate 60 --detach-other-monitors Save the text file as something like "remote-1080.bat". This particular configuration will change the resolution to a standard 1080p set the refresh rate for 60hz and detach any monitors other than your primary monitor. --detach-monitor-other-monitors will disable other displays preventing games from loading on a screen you can't see. Create a .bat for any resolution you plan to use with your rig. For example I have a Samsung s23 Ultra as a portable handheld so my configuration looks like this: resolution_change.exe --width 2316 --height 1080 --refreshrate 120 --detach-other-monitors If you have issues detaching the correct monitor open a PowerShell window in the same directory as the resolution_change.exe. Type cmd then type resolution_change.exe --list-displays Now you can change your script to detach only specified monitors you would do this by replacing --detach-other-monitors with --detach-monitor \\.\DISPLAY2 Ensure the monitor ID matches the monitor you want to detach. Now create another text file in the same directory and add the following: resolution_change.exe -r Save this file as "reset.bat" we will use this to re-attach monitors and change the resolution back to the original resolution. Now we will add these scripts as commands in Sunshine so they execute before we load our game desktop or Playnite. Return to Sunshine and navigate to the application you setup. Go to the "Command Preparation" section click the green "Add Commands" button. Your screen will now look like this: In the "Do Command" box paste the directory path for your "remote-1080.bat" script use the path copy method I outlined earlier. In the "Undo Command" box paste the directory path for your "reset.bat" script. When finished it should look something like this: Now when you load the application from the Moonlight client your resolution will automatically change. You may need to download a utility like CRU to add resolutions not normally supported by your system. You can download CRU here . Recommended Moonlight Client Settings I use the Moonlight client on several different devices for different purposes. I have it installed on my MacBook Pro my S23 Ultra my Galaxy Tablet and my Windows PC. Below I will give some rough guidelines for 720p 1080p and 1440p. Settings are basically the same across all Moonlight clients. Feel free to adjust these as you see fit: 720p I primarily use 720p when on a mobile network or wifi network with restricted speeds. Sunshine can use a lot of data and bandwidth so reducing the resolution and bitrate is a must. Here is a screenshot of the settings I use on Windows and MacOS devices: Feel free to experiment with the settings and adjust to your liking. On devices that support HDR I like to enable it in advanced settings: 1080p For 120 FPS add 10-15Mbps for the Video bitrate. 1440p For 120 FPS add 15-20Mbps for the Video bitrate. 4k For 120FPS add 30-40Mbps to the Video bitrate. Your system may default to similar settings and these are very network dependent. If you find a lot of network artifacting or slow connection you may need to reduce the bitrate. If you find that it's "grainy" or lower resolution you can try to increase the bitrate if your network speeds allow. If you need to reduce data usage you will want to use the lowest bitrate the network will support on mobile networks I find it's best to be at or under 25Mbps. A Word on Security It is possible to have Moonlight accessible from the internet using the Moonlight Internet Hosting tool. I will not cover that here it requires exposing ports and in my opinion that is very dangerous especially for remote access software. If you want to be able to access it outside your home network you can take that security risk the guide is available here . I would instead encourage you to use a VPN tunnel such as Wireguard Netmaker Tailscale or something similar. This will provide significantly more security and some routers may support Wireguard directly. This eliminates the need for open ports except the single port for the VPN tunnel reducing the potential threat attack surface. There are many articles on setting up VPN tunnels a quick simple solution would be wg-easy found here . Remote Rig Ready You should now have a setup for a fully remote gaming or VNC rig with the ability to specify custom resolutions using .bat scripts. You should also be setup to use Playnite as a basic unified or mobile console launcher and hopefully you have setup a VPN tunnel for remote access. This is an awesome way to play games work or access your network and systems remotely. You can easily set this up for a significant other child or family member with almost any device. Since the client is only acting as a screen for the stream it doesn't require a lot of power. You can give a second life to old phones tablets or laptops. Have fun with your new remote gaming rig stay tuned for the 2nd part where I will teach you how to fully virtualize your gaming rig and run it headless using software drivers. I will also write a 3rd article with more in depth Playnite setup for a complete professional and polished final product! 313492 2 -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- Ketchup306 Ā· Draft Ā· Apr 4, 2024 Ā· 1 min read Ā· 195 Views FREE, HIGH QUALITY GUIDES FOR HACKATHON PARTICIPANTS Hello everyone! I'm excited to announce that I've finally completed version 1 of my web app - Hackpost Guide ( https://www.hackpost.guide ). What is hackpost guide? It's similar to Scratch and dev.to serving as a platform where hackathon participants and everyday developers can share their work and tips. Essentially it's a "guide" for hackathon participants and aspiring developers. This app is a valuable resource particularly for the younger generation who are interested in development. What can you do? At present you can create an account make posts and like others' posts. Additional features will be introduced in the future. I encourage everyone to try it out (create an account and write posts!) and let me know if you encounter any bugs. 30195 1 -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- Who-am-I? Ā· Draft Ā· Apr 2, 2024 Ā· 9 min read Ā· 119 Views COLOR PICKER RESEARCH I had cost three days to research color picker. I wonder how does a painting web like Pixiv sketch youidraw have a color picker. You know if you ask a computer to calculate and display dense color values the computer will probably crash.So it's a magical thing. 1. The Simplest way: use input. HTML5 has supported you to pick color by <input type="color"> This element has provided the best color picker. If you don't know how to do it by yourself. You could straightly use it. 2. Color Checker Many picture painting or modifying apps has a color checker. Do you know how to do it? There is an idea copy this picture which you want to know by canvas and then use canvas to analyze the data of color (RGBA HEX HSL) The code: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0 maximum-scale=1.0 minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>pictocolour</title> </head> <body> <div id='idc'> <img id="examplec" src="https://pic4.zhimg.com/80/v2-8fa25a11b26eff364f26b10969317c0b_720w.jpg" alt="example"> <canvas width="6" height="6" id="colorp"></canvas> </div> <div> <p>The colour of point is</p><p id="pointin"></p> <div id="displayc"></div> </div> </body> <style> #colorp{ border: solid 2px; border-radius: 20px; z-index: 3; position: absolute; left: 18%; top: 35%; transform: translate(-50% -50%); } #displayc{ margin-left: 4px; border-style: solid; width: 40px; height: 20px; } </style> <script> const examplec=document.getElementById('examplec'); const colorp=document.getElementById('colorp'); const pointin=document.getElementById('pointin'); const displayc=document.getElementById('displayc') examplec.addEventListener('click' (event)=>{ const mouseX = event.clientX; const mouseY = event.clientY; const cRect = examplec.getBoundingClientRect(); const cLeft = cRect.left; const cTop = cRect.top; if (mouseX >= cLeft && mouseX <= cLeft + examplec.width && mouseY >= cTop && mouseY <= cTop + examplec.height) { const colorpX = mouseX - cLeft; const colorpY = mouseY - cTop; colorp.style.left = (mouseX + 10) + 'px'; colorp.style.top = (mouseY + 10) + 'px'; colorinfor(colorpX colorpY) } }) function colorinfor(colorpX colorpY){ const ctx=colorp.getContext('2d'); const img = new Image(); img.src = 'https://pic4.zhimg.com/80/v2-8fa25a11b26eff364f26b10969317c0b_720w.jpg'; img.crossOrigin = "Anonymous"; img.onload = function(){ ctx.clearRect(0 0 colorp.width colorp.height); ctx.drawImage(img -colorpX -colorpY); const pixelData = ctx.getImageData(0 0 colorp.width colorp.height).data; console.log('pixelData' pixelData) let redSum = 0 greenSum = 0 blueSum = 0; for (let i = 0; i < pixelData.length; i += 4) { redSum += pixelData[i]; greenSum += pixelData[i + 1]; blueSum += pixelData[i + 2]; } const pixelCount = pixelData.length / 4; const red = Math.round(redSum / pixelCount); const green = Math.round(greenSum / pixelCount); const blue = Math.round(blueSum / pixelCount); console.log("R: " + red + " G: " + green + " B: " + blue); pointin.innerHTML=`rgb(${red} ${green} ${blue})`; displayc.style.backgroundColor=`rgb(${red} ${green} ${blue})` } } </script> </html> 3. Combine two or more layers In the painting app especially in the professional one the layer is very important. So there is an operation to combine two layers. The idea is so simple paint twice in the same canvas: THE CODE: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0 maximum-scale=1.0 minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>PictureCombine</title> </head> <body> <div> <img src="https://hbimg.huaban.com/b4096cd152ac8db31a686e5af2c5e3ea5f0e6e8155a18-ff7QQn_fw658" alt="beachBackground" id="sea"> <img src="äøč½½2.png" alt="Ash Kuchetum" id="ash"> </div> <div> <canvas id="combine"></canvas> </div> </body> <style> #ash{ margin-left: -750px; } </style> <script> const sea = document.getElementById('sea'); const ash = document.getElementById('ash'); const combine = document.getElementById('combine'); window.onload = function() { const ctx = combine.getContext('2d'); combine.width = sea.width; combine.height = sea.height; ctx.drawImage(sea 0 0); ctx.drawImage(ash -125 -105); } </script> </html> 4. The Color Picker You had the idea of color checker and the layer combination. Now you can use this two idea to make a color picker. First make two layers an element to display colorful colors. It's better to use canvas to design this two layer because it's easier to combine into a picture by another canvas. Finally use the idea of color checker to analyze the color. THE CODE: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>colorpan</title> </head> <body> <div> <p>stamp:</p> <input type="color"> </div> <div> <p id="p1">The circle point is in</p><div id="pointin"></div><br> <p id="color">The color you pointed is</p><div id="colorname"></div> </div> <div> <div id="colorpan1"> <div id="colorpan2"></div> <canvas id="circlepoint"></canvas> </div> <div id="colors"> <div id="colorcard"></div> </div> </div> </body> <style> #colorpan1{ border-style: solid; width: 600px; height: 600px; cursor: pointer; position: relative; overflow-x: hidden; overflow-y: hidden; background: linear-gradient(to right #fff rgba(255 255 255 0)); } #colorpan2{ width: 600px; height: 600px; cursor: pointer; position: relative; background:linear-gradient(to top #000 rgba(0 0 0 0)); } #circlepoint { border-style: solid; width: 10px; height: 10px; border-radius: 20px; z-index: 3; position: absolute; left: 50%; top: 50%; transform: translate(-50% -50%); } #p1 #pointin{ display: inline-block; } #colors{ margin-top: 10px; border-style: solid; width: 600px; height: 60px; cursor: pointer; position: relative; background: linear-gradient(to right #f00 #ff0 #0f0 #0ff #00f #f0f #f00); } #colorcard{ margin-top: -6px; border-style: solid; width: 10px; height: 70px; background-color: white; position: absolute; left: 0; top: 0; } #color #colorname{ display: inline-block; } #colorname{ margin-left: 4px; border-style: solid; width: 40px; height: 20px; } </style> <script> const circlepoint = document.getElementById('circlepoint'); const colorpan1 = document.getElementById('colorpan1'); const colorpan2 = document.getElementById('colorpan2'); const pointin=document.getElementById('pointin'); const colors=document.getElementById('colors'); const colorcard = document.getElementById('colorcard'); const colorname=document.getElementById('colorname'); colorcard.addEventListener('mousedown' function(event) { event.preventDefault(); const offsetX = event.clientX - colorcard.getBoundingClientRect().left; const offsetY = event.clientY - colorcard.getBoundingClientRect().top; document.addEventListener('mousemove' onMouseMove); document.addEventListener('mouseup' onMouseUp); function onMouseMove(event) { const x = event.clientX - offsetX; const y = event.clientY - offsetY; const colorsRect = colors.getBoundingClientRect(); const colorsLeft = colorsRect.left; const colorsTop = colorsRect.top; const colorsRight = colorsRect.right - colorcard.offsetWidth; const colorsBottom = colorsRect.bottom - colorcard.offsetHeight; if (x >= colorsLeft && x <= colorsRight && y >= colorsTop && y <= colorsBottom) { colorcard.style.left = x + 'px'; colorcard.style.top = y + 'px'; } } function onMouseUp() { document.removeEventListener('mousemove' onMouseMove); document.removeEventListener('mouseup' onMouseUp); } }) document.addEventListener('click' function(event) { const mouseX = event.clientX; const mouseY = event.clientY; const colorpanRect = colorpan1.getBoundingClientRect(); const colorpanLeft = colorpanRect.left; const colorpanTop = colorpanRect.top; const colorpanRight = colorpanRect.right; const colorpanBottom = colorpanRect.bottom; if (mouseX >= colorpanLeft && mouseX <= colorpanRight && mouseY >= colorpanTop && mouseY <= colorpanBottom) { const circlepointX = mouseX - colorpanLeft; const circlepointY = mouseY - colorpanTop; circlepoint.style.left = circlepointX + 'px'; circlepoint.style.top = circlepointY + 'px'; pointin.innerText = `(${circlepointX} ${circlepointY})`; getColorAtPoint(circlepointX circlepointY); } colorcards(mouseX mouseY); }); function colorcards(mouseX mouseY){ const colorsRect = colors.getBoundingClientRect(); const colorsLeft = colorsRect.left; const colorsTop = colorsRect.top; const colorsRight = colorsRect.right; const colorsBottom = colorsRect.bottom; if (mouseX >= colorsLeft && mouseX <= colorsRight-8 && mouseY >= colorsTop && mouseY <= colorsBottom) { const circlepointX = mouseX - colorsLeft; colorcard.style.left = circlepointX + 'px'; const colorIndex = Math.floor(circlepointX / (colors.offsetWidth / 7)); const colorsArray = ['#f00' '#ff0' '#0f0' '#0ff' '#00f' '#f0f' '#f00']; colorpan1.style.background =` linear-gradient(to right #fff ${colorsArray[colorIndex]})`; } } function getColorAtPoint(circlepointX circlepointY) { const tempcanvas = document.createElement('canvas'); tempcanvas.width=colorpan1.clientWidth; tempcanvas.height=colorpan1.clientHeight; const temctx = tempcanvas.getContext('2d'); const computedStyle1 = getComputedStyle(colorpan1); const computedStyle2 = getComputedStyle(colorpan2); const background1 = computedStyle1.backgroundImage; console.log(background1) const background2 = computedStyle2.backgroundImage; let gradientObj1 gradientObj2; if (background1.includes('linear-gradient')) { const colors = background1.match(/rgba?\([^)]*\)|#[0-9a-fA-F]{3 6}/g); gradientObj1 = temctx.createLinearGradient(0 0 tempcanvas.width tempcanvas.height); for (let i = 0; i < colors.length; i++) { gradientObj1.addColorStop(i / (colors.length - 1) colors[i]); } } if (background2.includes('linear-gradient')) { const colors = background2.match(/rgba?\([^)]*\)|#[0-9a-fA-F]{3 6}/g); gradientObj2 = temctx.createLinearGradient(0 tempcanvas.height 0 0); for (let i = 0; i < colors.length; i++) { gradientObj2.addColorStop(i / (colors.length - 1) colors[i]); } } if (gradientObj1) { temctx.fillStyle = gradientObj1; temctx.fillRect(0 0 tempcanvas.width tempcanvas.height); } if (gradientObj2) { temctx.fillStyle = gradientObj2; temctx.fillRect(0 0 tempcanvas.width tempcanvas.height); } const ctx = circlepoint.getContext('2d'); const img = new Image(); img.src = tempcanvas.toDataURL(); img.onload = function () { ctx.clearRect(0 0 circlepoint.width circlepoint.height); const offsetX = circlepointX - circlepoint.width / 2; const offsetY = circlepointY - circlepoint.height / 2; const sourceWidth = circlepoint.width; const sourceHeight = circlepoint.height; ctx.imageSmoothingEnabled = true; ctx.imageSmoothingQuality = 'high'; ctx.drawImage(img offsetX offsetY sourceWidth sourceHeight 0 0 circlepoint.width circlepoint.height); const pixelData = ctx.getImageData(0 0 circlepoint.width circlepoint.height).data; console.log('pixelData' pixelData) let redSum = 0 greenSum = 0 blueSum = 0; for (let i = 0; i < pixelData.length; i += 4) { redSum += pixelData[i]; greenSum += pixelData[i + 1]; blueSum += pixelData[i + 2]; } const pixelCount = pixelData.length / 4; console.log('pixelCount' pixelCount); const r = Math.round(redSum / pixelCount); const g = Math.round(greenSum / pixelCount); const b = Math.round(blueSum / pixelCount); console.log("r g b" r g b); const hsl = rgbToHsl(r g b); const hex = rgbToHex(r g b); colorname.style.backgroundColor=hex; return { rgb: [r g b] hsl: hsl hex: hex }; } } function rgbToHsl(r g b) { r /= 255 g /= 255 b /= 255; const max = Math.max(r g b) min = Math.min(r g b); let h s l = (max + min) / 2; if (max === min) { h = s = 0; } else { const d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return [Math.round(h * 360) Math.round(s * 100) Math.round(l * 100)]; } function rgbToHex(r g b) { return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); } </script> </html> The code I showed has a small flaw that is the accuracy is not high enough. This idea in addition to painting can also be used to deal with the design of handwriting keyboards notes and other places that require color. 5. Project Code Address: https://github.com/MikeHe-creator/ColorLearn 12119 0 -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- Ben Herbst Ā· Draft Ā· Mar 31, 2024 Ā· 2 min read Ā· 253 Views OPEN MICROSOFT STORE APP FROM CMD You probably sometimes need to give an Application path for app automating purpose or something like remote control. But how can you get the path of a Microsoft Store App or open it from the Command Line? Here are the steps: Step 1: Open The Apps Folder Windows Explorer has a feature where you can view all the apps your device has installed which includes all the Microsoft Store Apps. To open this āfolderā you just need to press Win + R and enter shell:AppsFolder . Now press enter and you see an explorer virtual folder with all your apps: Step 2: Create an App Shortcut Right-click your Microsoft Store App and select āCreate Shortcutā: As the applications āfolderā is not really a folder Windows is going to ask you to create a shortcut on the Desktop instead as you can't add files to this virtual folder. Just click on yes. You may move the shortcut later. Step 3: Using the Shortcut Now that you created an application shortcut you are finally able to open the Microsoft Store App via the Command Line via the shortcut. You can now also finally reference it in applications like Sunshine about which I also write a blog post in my DevsForDevs profile. Check the file name and path in its properties: Then enter it in CMD like this: That's all. Now you can open any Microsoft App via a file path! 20253 0 -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- Ben Herbst Ā· Draft Ā· Mar 29, 2024 Ā· 6 min read Ā· 4167 Views SUNSHINE: SELF HOSTED GOOGLE STADIA OR GEFORCE NOW Have you ever dreamt of playing on your gaming pc which is at home from a device like your laptop or smartphone? Enter Sunshine ā a game streaming service that breaks down barriers by allowing you to play games using your own hardware. What's more it's 100% open source giving you the freedom to customize and explore to your heart's content. Let's delve into what makes Sunshine shine and why it's a game-changer for gamers everywhere. Sunshine's biggest draw is its compatibility with your existing hardware. You don't need a fancy system or cutting-edge technology always around you to enjoy your favourite games. Whether you're using a smartphone tablet laptop or even a humble desktop computer Sunshine seamlessly integrates with your device turning it into a powerful gaming platform. If you already have an awesome gaming setup at home this makes it available all around the world via the Wi-Fi like GeForce NOW. What sets Sunshine apart from other game streaming services is its commitment to open source principles. Unlike closed systems that restrict access and customization Sunshine embraces openness allowing users to tinker with the code and tailor their gaming experience to suit their preferences. This level of freedom empowers users to explore new possibilities and contribute to the platform's development fostering a vibrant community of creators and innovators. Another advantage of Sunshine's open source nature is transparency. Users can inspect the code to ensure security and privacy giving them peace of mind knowing that their data is protected. This transparency builds trust and fosters a collaborative environment where users and developers work together to improve the platform continuously. But what about the games? You can play all the games that you have on your pc and Steam even has an awesome integration with their Big Picture service ( https://store.steampowered.com/bigpicture ) which gives your steam library an awesome look and feel on touch devices and also devices like TVs. Get Started Your Gaming PC is the Server and your devices that stream it like your phone laptops iPads or other tablets are all clients. Sunshine bases on the open source moonlight software which are also the client apps which are available for your desktops and mobile devices. You can download the clients at https://moonlight-stream.org/ . Furthermore to set up the server you need to download the server software on your gaming pc at https://app.lizardbyte.dev/Sunshine/?lng=de. Simply download the .exe of it and install it. After you installed it run it. You will see a tray icon: Click on that icon. Then click on āOpen Sunshineā. There you find a panel where you need to input a new username and password. Do that and don't forget your password as you need it for all the clients to open sunshine later on. After that you will find yourself in the view: Here you can find some information which you can overall ignore. Most of the settings and stuff are also only if you get into trouble. To see all your available applications which are already setup for you and which you can play on your clients click on āapplicationsā. There you can find a form where you can add a new application. The most required information for adding an application in Sunshine is the Application Name and the Command so Sunshine can find and execute your application. This needs to be a file path which you can also open in cmd by pasting it in. If the file path includes spaces you need to use quotation marks around it. You can find the file paths of your applications / games by right-clicking them in the taskbar like this: There you will probably find a .exe file. If you installed it through for example the Microsoft Store you will need to use a workaround. You are able to find that workaround in my DevsForDevs profile in another separate post. Now that you have the path of your .exe just paste it into sunshine and click add. That's it. The Clients I described already above that you need to install the Moonlight clients from https://moonlight-stream.org/ as Sunshine bases on Moonlight. Just open the client and it will probably auto discover your Sunshine Server. Then you just have to click on it and a code is going to appear which you need to enter into Sunshine. If the server doesn't auto appear click on āAdd Host Manuallyā. There you need to enter the IP Address of the Server Device. Then click on OK and It's going to connect to it: When you are in your Device you can select a Game: Click on your game that you want to play. Now the magic happens and the game starts āon your phoneā. As most Desktop Games don't support touch controls but controllers Moonlight comes with a built-in virtual controller. If you prefer a real controller connect your PlayStation Xbox or whatever controller to your pc and play! You may want to adjust the settings to use a higher resolution like 4k but it may slow down your connection which makes the game lag. So play around a bit with it and find what fits the best for your use-case. Be aware that you can't play outside your LAN already. To do that you need to set up a VPN or do some other ways. I post an article about how to do that in my DevsForDevs profile as well so check it out! Conclusion I hope you clicked this article and you are going to have a fun time playing all your favourite PC games with your PC power on all your other clients! 214167 0 -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- DO YOU LIKE THE PROJECT? Donate some money to help with server costs etc. :D Donate START WRITING TODAY! Create your account today and join the helpful development community! Login Signup FOLLOW US! And receive the latest news, never miss something from us anymore! * * * * DevsForDevs Discover a world of insightful articles, engaging stories, and vibrant discussions on our platform. Crafted with love by Ben Herbst, and many contributors! PrivacyImprintTerms of UseCode of ConductReport COMMENTS -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- COMMENTS -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- COMMENTS -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- COMMENTS -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- COMMENTS -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- COMMENTS -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- COMMENTS -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- COMMENTS -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- COMMENTS -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- COMMENTS -------------------------------------------------------------------------------- --------------------------------------------------------------------------------