• What Do You Need Help With? V8
    1,074 replies, posted
given the restrictions on the left, can anyone spot a logical fallacy that would cause an issue with the restrictions? [t]http://i.imgur.com/Myuk59W.png[/t] i've gone through it i dunno how many times now and it seems sound proof to me, and i've been running it in a python sandbox with all sorts of input and nothing seems wrong, but i'm failing 2 test cases and i don't know what those cases are because it doesn't tell me lol
I've got a table like this: [code] id| group| value| ------*----------*---------* 1| 1| 8| 2| 1| 20| 3| 2| 10| 4| 2| 12| 5| 2| 8| [/code] Notice the group category. Basically, I want to get the latest record in each group and subtract it from the earliest record in each group, so the final query should look like: [code] group| difference| ----------*------------* 1| 12| 2| -2| [/code]
I have somewhat successfully implemented a few algorithms for generating a triangulated vertex list for a mesh given a list of points in 3D My problem now is the winding order. There has to be some sort of solution to get all triangles wound in a direction to force their normals to point away from the center or something. I just need some sort of logic to get my triangles facing a direction assuming that the mesh is a convex hull or some sort of closed off hull. My idea was to calculate the normal of the triangle, and take the direction from the center of the triangle to the center of the mesh, and if the dot product between them is positive then swap 2 of the vertices with each other. This solves some but not all cases. I really don't know what to do, this seems like it should be such a trivial problem. I'd prefer [B]not [/B]having to disable backface culling just for these triangles [code] for (int x = 0, x_size = vertices.size(); x < x_size; x += 3) { const vec3 point1 = vertices[x]; const vec3 point2 = vertices[x + 1]; const vec3 point3 = vertices[x + 2]; const vec3 triangle_center = (point1 + point2 + point3) / 3.0f; const vec3 normal = glm::normalize(glm::cross(point1 - point2, point1 - point3)); const vec3 viewing = glm::normalize(center - triangle_center); const float dot = glm::dot(normal, viewing); if (dot >= 0.0f) { // Swap } } [/code]
[B]I've been working on a project called Borealis Server Manager since May of this year. I need help from anyone skilled enough in C# to do the following:[/B] - Allow the user to start multiple gameserver processes with arguments given to them, in upwards of dozens or hundreds of them as background processes, and still be able to switch the redirected output and input to those processes on-the-fly to the console window within Borealis. This is what the console page looks like in Borealis: [img]https://i.imgur.com/U9bCbQJ.png[/img] This is the code that currently launches the programs, merged with some code that was suggested by another Facepunch user months ago, but their new code seems to freeze Borealis while even one server is running, which is actually a step backwards, and I can't even get it to properly redirect console output into my console window in Borealis. I am completely okay with a rewrite of the code should someone step up to help Borealis enter beta stages. I've had the code functional enough to launch the servers externally, but internally, I can only get one server's output at a time, without killing all of the other servers. It's a pretty complex problem. [code] using MetroFramework; using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace Borealis { public partial class TAB_CONTROL : Form { #region pInvoke [DllImport("kernel32.dll", SetLastError = true)] static extern bool AttachConsole(uint dwProcessId); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern bool FreeConsole(); [DllImport("kernel32.dll")] static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add); // Delegate type to be used as the Handler Routine for SCCH delegate Boolean ConsoleCtrlDelegate(CtrlTypes CtrlType); // Enumerated type for the control messages sent to the handler routine enum CtrlTypes : uint { CTRL_C_EVENT = 0, CTRL_BREAK_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT = 5, CTRL_SHUTDOWN_EVENT } [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId); public static void StopProgramByAttachingToItsConsoleAndIssuingCtrlCEvent(Process proc) { //This does not require the console window to be visible. if (AttachConsole((uint)proc.Id)) { //Disable Ctrl-C handling for our program SetConsoleCtrlHandler(null, true); GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0); //Must wait here. If we don't and re-enable Ctrl-C handling below too fast, we might terminate ourselves. var wasAborted = false; var procTask = Task.Run(() => { //This is necessary because when we kill the process, it obviously exits. At that point, there is no proc object to wait for any longer if (!wasAborted) proc.WaitForExit(); }); if (!procTask.Wait(10000)) { wasAborted = true; proc.Kill(); } FreeConsole(); //Re-enable Ctrl-C handling or any subsequently started programs will inherit the disabled state. SetConsoleCtrlHandler(null, false); } } #endregion private CancellationTokenSource cancelToken; public TAB_CONTROL() { InitializeComponent(); } //===================================================================================// // UI HANDLING CODE // //===================================================================================// private void ServerControl_Load(object sender, EventArgs e) { //Pull all gameserver data from gameservers.json, split all json strings into a list, iterate through that list for specific data. if (GameServer_Management.server_collection != null) { foreach (GameServer_Object gameserver in GameServer_Management.server_collection) { comboboxGameserverList.Items.Add(gameserver.SERVER_name_friendly); } } } private void comboboxGameserverList_SelectedValueChanged(object sender, EventArgs e) { foreach (GameServer_Object gameserver in GameServer_Management.server_collection) { if (gameserver.SERVER_name_friendly == comboboxGameserverList.Text) { //Decide what data to pull from the object at this point in time of development. GameServer_Object Controlled_GameServer = new GameServer_Object(); Controlled_GameServer.DIR_install_location = Controlled_GameServer.DIR_install_location; Controlled_GameServer.SERVER_executable = Controlled_GameServer.SERVER_executable; Controlled_GameServer.SERVER_launch_arguments = Controlled_GameServer.SERVER_launch_arguments; Controlled_GameServer.SERVER_running_status = Controlled_GameServer.SERVER_running_status; } } btnStartServer.Visible = true; chkAutoRestart.Visible = true; lblAutoRestart.Visible = true; chkStandaloneMode.Visible = true; lblStandaloneMode.Visible = true; consolePanel.Visible = true; } private void proc_DataReceived(object sender, DataReceivedEventArgs e) { if (e.Data != null) { consoleOutputList.Items.Add(e.Data); } } private void RefreshData() { comboboxGameserverList.Items.Clear(); if (GameServer_Management.server_collection != null) { foreach (GameServer_Object gameserver in GameServer_Management.server_collection) { comboboxGameserverList.Items.Add(gameserver.SERVER_name_friendly); } } } private void ServerControl_Activated(object sender, EventArgs e) { RefreshData(); } private void chkStandaloneMode_OnValueChange(object sender, EventArgs e) { if (chkStandaloneMode.Value == true) { consolePanel.Visible = false; } else { consolePanel.Visible = true; } } //===================================================================================// // SERVER CONTROL: // //===================================================================================// private void LaunchServer(string SERVER_executable, string SERVER_launch_arguments, Action<string> redirectedOutputCallback = null, TextReader input = null, string argWorkingDirectory = null, EventHandler onExitedCallback = null, CancellationToken cancelToken = default(CancellationToken)) { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.Arguments = SERVER_launch_arguments; startInfo.FileName = SERVER_executable; if (redirectedOutputCallback != null) //Redirect Output to somewhere else. { startInfo.UseShellExecute = false; //Redirect the programs. startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.RedirectStandardError = true; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardInput = true; startInfo.ErrorDialog = false; try { // Start the process with the info we specified. // Call WaitForExit and then the using statement will close. using (var process = Process.Start(startInfo)) { if (onExitedCallback != null) { process.EnableRaisingEvents = true; process.Exited += onExitedCallback; } if (cancelToken != null) { cancelToken.Register(() => { StopProgramByAttachingToItsConsoleAndIssuingCtrlCEvent(process); redirectedOutputCallback?.Invoke("Shutting down the server..."); }); } process.OutputDataReceived += (sender, args) => { if (!string.IsNullOrEmpty(args?.Data)) redirectedOutputCallback(args.Data); }; process.BeginOutputReadLine(); process.ErrorDataReceived += (sender, args) => { if (!string.IsNullOrEmpty(args?.Data)) redirectedOutputCallback(args.Data); }; process.BeginErrorReadLine(); //For whenever input is needed string line; while (input != null && (line = input.ReadLine()) != null) process.StandardInput.WriteLine(line); process.WaitForExit(); } } catch { StringBuilder errorDialog = new StringBuilder(); errorDialog.Append("There was an error launching the following server:\n") .Append(startInfo.FileName) .Append("\n\n") .Append("[Retry]: Attempt to start the same server again.\n") .Append("[Cancel]: Cancel attempting to start server."); } } else //No not redirect output somewhere else { startInfo.UseShellExecute = true; //Execute the programs. try { // Start the process with the info we specified. // Call WaitForExit and then the using statement will close. using (Process exeProcess = Process.Start(startInfo)) { exeProcess.WaitForExit(); } } catch { StringBuilder errorDialog = new StringBuilder(); errorDialog.Append("There was an error launching the following server:\n") .Append(startInfo.FileName) .Append("\n\n") .Append("[Retry]: Attempt to start the same server again.\n") .Append("[Cancel]: Cancel attempting to start server."); } } } private void btnStartServer_Click(object sender, EventArgs e) { if (GameServer_Management.server_collection != null) { foreach (GameServer_Object gameserver in GameServer_Management.server_collection) { if (gameserver.SERVER_name_friendly == comboboxGameserverList.Text) { //SOURCE ENGINE HANDLER if (gameserver.ENGINE_type == "SOURCE") { //Check to see if the gameserver needs to be run with a visible console, or directly controlled by Borealis. if (chkStandaloneMode.Value == true) //To be hopefully depreciated soon. Only needed right now as a fallback option to server operators. { LaunchServer(gameserver.DIR_install_location + @"\steamapps\common" + gameserver.DIR_root + gameserver.SERVER_executable, string.Format("{0} +port {1} +map {2} +maxplayers {3}", gameserver.SERVER_launch_arguments, gameserver.SERVER_port, gameserver.GAME_map, gameserver.GAME_maxplayers)); } else { LaunchServer(gameserver.DIR_install_location + @"\steamapps\common" + gameserver.DIR_root + gameserver.SERVER_executable, string.Format("{0} +port {1} +map {2} +maxplayers {3}", gameserver.SERVER_launch_arguments, gameserver.SERVER_port, gameserver.GAME_map, gameserver.GAME_maxplayers)); } } //SOURCE ENGINE HANDLER if (gameserver.ENGINE_type == "UNREAL") { //Check to see if the gameserver needs to be run with a visible console, or directly controlled by Borealis. if (chkStandaloneMode.Value == true) { /*LaunchServer(gameserver.DIR_install_location + @"\steamapps\common" + gameserver.DIR_root + gameserver.SERVER_executable, string.Format("{0}?{1}?Port={2}?MaxPlayers={3}", gameserver.GAME_map, gameserver.SERVER_launch_arguments, gameserver.SERVER_port, gameserver.GAME_maxplayers)); */ } else { MetroMessageBox.Show(BorealisServerManager.ActiveForm, "Unfortunately Borealis cannot directly control console output at this time; instead, please launch the server in 'standalone mode'.", "Unable to launch server within Borealis.", MessageBoxButtons.OK, MessageBoxIcon.Error); /* chkAutoRestart.Visible = false; lblAutoRestart.Visible = false; chkStandaloneMode.Visible = false; lblStandaloneMode.Visible = false; btnStartServer.Enabled = false; btnStopServer.Visible = true; consolePanel.Visible = true; txtboxIssueCommand.Visible = true; txtboxIssueCommand.Text = " > Enter a Command"; txtboxIssueCommand.Enabled = true; Execute(Environment.CurrentDirectory + gameserver.SERVER_executable, gameserver.SERVER_launch_arguments, true); */ } } } } } } private void btnStopServer_Click(object sender, EventArgs e) { btnStopServer.Visible = false; btnStartServer.Enabled = true; chkAutoRestart.Visible = true; lblAutoRestart.Visible = true; txtboxIssueCommand.Visible = false; consoleOutputList.Items.Clear(); txtboxIssueCommand.Text = " > Server is Not Running"; txtboxIssueCommand.Enabled = false; cancelToken.Cancel(); backgroundWorker01.RunWorkerCompleted += (sender2, e2) => { btnStopServer.Enabled = false; btnStartServer.Enabled = true; txtboxIssueCommand.Enabled = false; txtboxIssueCommand.Text = "> Server is not running"; consoleOutputList.Items.Add("Server stopped..."); }; } private void txtboxIssueCommand_Enter(object sender, EventArgs e) { txtboxIssueCommand.Text = ""; } private void txtboxIssueCommand_MouseClick(object sender, MouseEventArgs e) { txtboxIssueCommand.Text = ""; } private void backgroundWorker01_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { bool stopped = false; //It's an assumption that these 3 elements MUST exist var asyncCallback = comboboxGameserverList.BeginInvoke((Func<string[]>)delegate () { return new string[] { //GameServerXMLData( comboboxGameserverList.SelectedItem as string, "installation_folder" ), //GameServerXMLData( comboboxGameserverList.SelectedItem as string, "default_launchscript" ), //GameServerXMLData( comboboxGameserverList.SelectedItem as string, "binaries" ) }; }); asyncCallback.AsyncWaitHandle.WaitOne(); var serverParams = comboboxGameserverList.EndInvoke(asyncCallback) as string[]; Action<string> textAddCallback = (args) => { consoleOutputList.BeginInvoke((Action)delegate () { consoleOutputList.Items.Add(args); }); }; EventHandler exitedHandler = (sender2, e2) => { if (!cancelToken.IsCancellationRequested) { //Wait a little until we restart the server consoleOutputList.BeginInvoke((Action)delegate () { consoleOutputList.Items.Add(Environment.NewLine); consoleOutputList.Items.Add(Environment.NewLine); consoleOutputList.Items.Add(Environment.NewLine); consoleOutputList.Items.Add("An error occured and the process has crashed. Auto-restarting in 5 seconds..."); //Scroll to the bottom consoleOutputList.TopIndex = consoleOutputList.Items.Count - 1; consoleOutputList.Items.Add(Environment.NewLine); consoleOutputList.Items.Add(Environment.NewLine); consoleOutputList.Items.Add(Environment.NewLine); }); Thread.Sleep(5000); } else stopped = true; }; while (chkAutoRestart.Value && !stopped) LaunchServer(serverParams[0] + serverParams[2], serverParams[1], textAddCallback, null, serverParams[0], chkAutoRestart.Value ? exitedHandler : null, chkAutoRestart.Value ? cancelToken.Token : default(System.Threading.CancellationToken)); } } } [/code]
I'm trying to write a tool in C# that can upload items to the steam workshop for a mod. I'm using Steamworks.NET. Everything seems to work before submitting the update, but whenever I try to submit the update it fails because it doesn't like something about the content path I set. [code]updateHandle = SteamUGC.StartItemUpdate((AppId_t)COID, (PublishedFileId_t)currentFileId); SteamUGC.SetItemTitle(updateHandle, tbTitle.Text); SteamUGC.SetItemDescription(updateHandle, tbDescription.Text); SteamUGC.SetItemPreview(updateHandle, previewImagePath); SteamUGC.SetItemContent(updateHandle, tempFolder + @"\addons"); resSubmitUpdate.Set(SteamUGC.SubmitItemUpdate(updateHandle, "Initial upload"), OnUpdateDone);[/code] For some reason I get a k_EResultInvalidParam. If I comment out the SteamUGC.SetItemContent line everything works. The update goes through and is reflected in the steam workshop. I'm using a open file dialog to select a vpk file that gets copied to a temporary folder, from which the folder is selected (C:\Users\User\AppData\Local\Temp\Workshop\addons) I'm at a complete loss. Someone linked me their uploader but I can't really make sense of it since I can't get it working without the steam api.
I want to draw things efficiently in SDL. I've got a tilemap that's static: it won't change. It looks something like this: [code] int map[5][5] = { {1,1,1,1,1}, {1,0,0,0,1}, {1,0,0,0,1}, {1,0,0,0,1}, {1,1,1,1,1} };[/code] instead of calling a draw method for every tile, I figured I could draw all the tiles once to some kind of buffer, and then just draw that buffer every loop. I'm new to SDL, so I have no idea how to do this. I know how to do it in SFML and in HTML5 canvas, but I don't know anything about SDL
[QUOTE=WhiteWhiskers;52536978][B]I've been working on a project called Borealis Server Manager since May of this year. I need help from anyone skilled enough in C# to do the following:[/B] - Allow the user to start multiple gameserver processes with arguments given to them, in upwards of dozens or hundreds of them as background processes, and still be able to switch the redirected output and input to those processes on-the-fly to the console window within Borealis. This is what the console page looks like in Borealis: *img* [/QUOTE] So, hopefully this is useful: [code] <Query Kind="Program"> <Namespace>System.Runtime.InteropServices</Namespace> <Namespace>System.Threading.Tasks</Namespace> <Namespace>System.Runtime.CompilerServices</Namespace> <Namespace>System.Collections.Concurrent</Namespace> </Query> #define TRACE void Main() { //ProcessHelper.traceSwitch.Level = TraceLevel.Warning; ProcessHelper.traceSwitch.Level = TraceLevel.Verbose; { Console.WriteLine("\r\n// silly test: start notepad and kill it via dispose"); var test = new ProcessHelper("notepad", "notepad.exe", string.Empty); test.EventOccured += (sender, args) => Console.WriteLine(args); test.Start(); Thread.Sleep(100); test.Dispose(); Thread.Sleep(1000); } { Console.WriteLine("\r\n// silly test: start notepad and stop, then dispose"); var test = new ProcessHelper("notepad", "notepad.exe", string.Empty); test.EventOccured += (sender, args) => Console.WriteLine(args); test.Start(); Thread.Sleep(100); test.Stop(); Thread.Sleep(100); test.Dispose(); Thread.Sleep(100); } { Console.WriteLine("\r\n// silly test: start notepad and stop, then start, then dispose"); var test = new ProcessHelper("notepad", "notepad.exe", string.Empty); test.EventOccured += (sender, args) => Console.WriteLine(args); test.Start(); Thread.Sleep(100); test.Stop(); Thread.Sleep(100); test.Start(); Thread.Sleep(100); test.Dispose(); Thread.Sleep(100); } } public enum ProcessHelperEventType { OutputMessage, ErrorMessage, ProcessStarted, ProcessStopped } // basic event type for the process helper public class ProcessHelperEvent { public ProcessHelperEvent(string message, ProcessHelperEventType type, string nickname, int? pid) { Message = message; Type = type; Occurred = DateTimeOffset.Now; ProcessNickname = nickname; Pid = pid; } public int? Pid { get; } public string ProcessNickname { get; } public string Message { get; } public ProcessHelperEventType Type { get; } public DateTimeOffset Occurred { get; } } // Goal of this class is to wrap all process start / stop logic // we avoid blocking methods on the public methods in general here // keep a buffered log of console redirect content // ensure methods defined are thread safe in case someone gets click happy in a UI somewhere ;) public interface IProcess : IDisposable { bool IsRunning { get; } void Start(); // start this process if not already void Stop(); // ask process to close nicely void Kill(); // kick chair out from under the process event EventHandler<ProcessHelperEvent> EventOccured; // an event transpired IEnumerable<ProcessHelperEvent> ProcessEvents { get; } // events currently stored } public class ProcessHelper : IProcess { public static readonly TraceSwitch traceSwitch = new TraceSwitch("Process", "Process manager info"); private readonly string nickname; private readonly string SERVER_executable; private readonly string SERVER_launch_arguments; private readonly object processSync = new object(); private readonly ConcurrentQueue<ProcessHelperEvent> processEvents = new ConcurrentQueue<ProcessHelperEvent>(); private bool disposed; private Process currentProcess; [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); const int SW_HIDE = 0; const UInt32 WM_CLOSE = 0x0010; // ask nicely to close window public ProcessHelper(string nickname, string SERVER_executable, string SERVER_launch_arguments) { this.nickname = nickname; this.SERVER_executable = SERVER_executable; this.SERVER_launch_arguments = SERVER_launch_arguments; } public event EventHandler<ProcessHelperEvent> EventOccured; public IEnumerable<ProcessHelperEvent> ProcessEvents => processEvents; // inaccurate, but good enough with the other aspects of this helper public bool IsRunning => currentProcess != null; public void Start() { lock (processSync) { DisposeGuard(); if (currentProcess != null) { return; } ProcessStartInfo startInfo = new ProcessStartInfo(); // let's be kind here! we want to use WM_CLOSE as a graceful close attempt, and we need a window for that // insead, lets hide the window all sneaky like startInfo.CreateNoWindow = false; startInfo.Arguments = SERVER_launch_arguments; startInfo.FileName = SERVER_executable; startInfo.UseShellExecute = false; //Redirect the programs. startInfo.RedirectStandardError = true; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardInput = true; startInfo.ErrorDialog = false; var process = new Process(); process.EnableRaisingEvents = true; process.OutputDataReceived += (sender, args) => DataRecieved(args,false); process.ErrorDataReceived += (sender, args) => DataRecieved(args,true); process.StartInfo = startInfo; process.Exited += (sender, args) => ProcessClosed(process); TraceMessage(TraceLevel.Verbose, $"about to start process {nickname} @'{SERVER_executable}'"); if (!process.Start()) { throw new Exception($"cannot get the process {nickname} @'{SERVER_executable}' to start - returns false"); } OnEventOccurred(new ProcessHelperEvent(null, ProcessHelperEventType.ProcessStarted, nickname, process?.Id)); TraceMessage(TraceLevel.Info, $"process {nickname} started with pid {process.Id} @'{SERVER_executable}'"); //note: only works as long as your process actually creates a main window. while (process.MainWindowHandle == IntPtr.Zero) { System.Threading.Thread.Sleep(10); } // this hides the window without disable message pumping ShowWindow(process.MainWindowHandle, SW_HIDE); TraceMessage(TraceLevel.Verbose, $"window hidden for {nickname} pid {process.Id}"); currentProcess = process; } } public void Stop() { lock (processSync) { DisposeGuard(); if (currentProcess == null) { TraceMessage(TraceLevel.Warning, $"attempted to stop process {nickname} when no process is running - likely a race condition!"); return; } SendMessage(currentProcess.MainWindowHandle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); TraceMessage(TraceLevel.Verbose, $"sent WM_CLOSE to process {nickname} pid {currentProcess.Id}"); } } public void Kill() { lock (processSync) { DisposeGuard(); if (currentProcess == null) { TraceMessage(TraceLevel.Warning, $"attempted to KILL process {nickname} when no process is running - likely a race condition!"); return; } currentProcess.Kill(); TraceMessage(TraceLevel.Warning, $"KILLED process {nickname} pid {currentProcess.Id}"); currentProcess.Dispose(); currentProcess = null; } } public void Dispose() { lock (processSync) { if (!disposed && currentProcess != null) { TraceMessage(TraceLevel.Warning, $"KILLING {nickname} beccause you forgot to stop it before calling Dispose"); // welp, time waits for no one! currentProcess.Kill(); currentProcess = null; } else if (!disposed) { TraceMessage(TraceLevel.Verbose, $"diposed {nickname} gracefully, good job!"); } disposed = true; } } private void ProcessClosed(Process process) { lock (processSync) { OnEventOccurred(new ProcessHelperEvent(null, ProcessHelperEventType.ProcessStopped, nickname, process?.Id)); TraceMessage(TraceLevel.Info, $"process {nickname} pid {process?.Id} has closed, RIP"); process.Dispose(); if (currentProcess == process) { currentProcess = null; } } } private void DataRecieved(DataReceivedEventArgs args, bool wasError) { lock (processSync) { var type = wasError ? ProcessHelperEventType.ErrorMessage : ProcessHelperEventType.OutputMessage; OnEventOccurred(new ProcessHelperEvent(args.Data, type, nickname, currentProcess?.Id )); } } private void DisposeGuard([CallerMemberName] string callerName = "") { if (disposed) { throw new Exception($"attempted to call {callerName} after a dispose!!"); } } private void OnEventOccurred(ProcessHelperEvent args) { processEvents.Enqueue(args); EventOccured?.Invoke(this, args); } private static void TraceMessage(TraceLevel level, string message) { if (traceSwitch.Level >= level) { Trace.WriteLine(message, "Process"); } } } [/code] It is a quick linqpad script, but you can make it a regular console app by making Main() work. The for a 'test' is as follows: [img]http://i.imgur.com/mEomfpk.png[/img] Does this help at all? Basic idea is to use the same process method you created and wrap it into a pretty, non-blocking, thread safe bow. I imagine you'd simply enumerate the "ProcessEvents" for the log. Start and stop happens on one process. Each process/server is a single "ProcessHelper" instance. Note: you probably want to flush the "ProcessEvents" buffer so it is max 1000 lines or some such, likewise I don't like the event handler since they are easy to leak / mess up while plumbing (I'd prefer making it observable but might not be useful for you).
Regarding CSS, how can I change certain objects depending on the user? I know I worded that poorly, so here's an example: [QUOTE][IMG]http://i.imgur.com/N5gw8oF.png[/IMG][/QUOTE] Using CSS, how can I change stuff like the picture, modify the name, etc? I'd like to give certain users some special stuff, like names with colored shadows or whatever. I was thinking I could do it with their account ID (His is 10063, mine is 721043) [editline]6th August 2017[/editline] An example would be nice too, I'm not necessarily proficient in CSS, but I'd like to learn.
You could use the name (there's some CSS selector that matches text but from memory there's a bunch of gotchas). Looks like the user id is in the CSS though (.user_721043 is all the user info). .user_721043 { background: red; } would colour the background of the user info red for example. For modifying the image that's a bit harder but possibly background-image on the parent class and display: none or visibility: hidden on the image itself might work.
[QUOTE=tschumann;52544330]You could use the name (there's some CSS selector that matches text but from memory there's a bunch of gotchas). Looks like the user id is in the CSS though (.user_721043 is all the user info). .user_721043 { background: red; } would colour the background of the user info red for example. For modifying the image that's a bit harder but possibly background-image on the parent class and display: none or visibility: hidden on the image itself might work.[/QUOTE] I've tried that specific snippet you posted there and nothing seemed to happen. Would you know why?
[QUOTE=bord2tears;52542695]So, hopefully this is useful: [code] <Query Kind="Program"> <Namespace>System.Runtime.InteropServices</Namespace> <Namespace>System.Threading.Tasks</Namespace> <Namespace>System.Runtime.CompilerServices</Namespace> <Namespace>System.Collections.Concurrent</Namespace> </Query> #define TRACE void Main() { //ProcessHelper.traceSwitch.Level = TraceLevel.Warning; ProcessHelper.traceSwitch.Level = TraceLevel.Verbose; { Console.WriteLine("\r\n// silly test: start notepad and kill it via dispose"); var test = new ProcessHelper("notepad", "notepad.exe", string.Empty); test.EventOccured += (sender, args) => Console.WriteLine(args); test.Start(); Thread.Sleep(100); test.Dispose(); Thread.Sleep(1000); } { Console.WriteLine("\r\n// silly test: start notepad and stop, then dispose"); var test = new ProcessHelper("notepad", "notepad.exe", string.Empty); test.EventOccured += (sender, args) => Console.WriteLine(args); test.Start(); Thread.Sleep(100); test.Stop(); Thread.Sleep(100); test.Dispose(); Thread.Sleep(100); } { Console.WriteLine("\r\n// silly test: start notepad and stop, then start, then dispose"); var test = new ProcessHelper("notepad", "notepad.exe", string.Empty); test.EventOccured += (sender, args) => Console.WriteLine(args); test.Start(); Thread.Sleep(100); test.Stop(); Thread.Sleep(100); test.Start(); Thread.Sleep(100); test.Dispose(); Thread.Sleep(100); } } public enum ProcessHelperEventType { OutputMessage, ErrorMessage, ProcessStarted, ProcessStopped } // basic event type for the process helper public class ProcessHelperEvent { public ProcessHelperEvent(string message, ProcessHelperEventType type, string nickname, int? pid) { Message = message; Type = type; Occurred = DateTimeOffset.Now; ProcessNickname = nickname; Pid = pid; } public int? Pid { get; } public string ProcessNickname { get; } public string Message { get; } public ProcessHelperEventType Type { get; } public DateTimeOffset Occurred { get; } } // Goal of this class is to wrap all process start / stop logic // we avoid blocking methods on the public methods in general here // keep a buffered log of console redirect content // ensure methods defined are thread safe in case someone gets click happy in a UI somewhere ;) public interface IProcess : IDisposable { bool IsRunning { get; } void Start(); // start this process if not already void Stop(); // ask process to close nicely void Kill(); // kick chair out from under the process event EventHandler<ProcessHelperEvent> EventOccured; // an event transpired IEnumerable<ProcessHelperEvent> ProcessEvents { get; } // events currently stored } public class ProcessHelper : IProcess { public static readonly TraceSwitch traceSwitch = new TraceSwitch("Process", "Process manager info"); private readonly string nickname; private readonly string SERVER_executable; private readonly string SERVER_launch_arguments; private readonly object processSync = new object(); private readonly ConcurrentQueue<ProcessHelperEvent> processEvents = new ConcurrentQueue<ProcessHelperEvent>(); private bool disposed; private Process currentProcess; [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); const int SW_HIDE = 0; const UInt32 WM_CLOSE = 0x0010; // ask nicely to close window public ProcessHelper(string nickname, string SERVER_executable, string SERVER_launch_arguments) { this.nickname = nickname; this.SERVER_executable = SERVER_executable; this.SERVER_launch_arguments = SERVER_launch_arguments; } public event EventHandler<ProcessHelperEvent> EventOccured; public IEnumerable<ProcessHelperEvent> ProcessEvents => processEvents; // inaccurate, but good enough with the other aspects of this helper public bool IsRunning => currentProcess != null; public void Start() { lock (processSync) { DisposeGuard(); if (currentProcess != null) { return; } ProcessStartInfo startInfo = new ProcessStartInfo(); // let's be kind here! we want to use WM_CLOSE as a graceful close attempt, and we need a window for that // insead, lets hide the window all sneaky like startInfo.CreateNoWindow = false; startInfo.Arguments = SERVER_launch_arguments; startInfo.FileName = SERVER_executable; startInfo.UseShellExecute = false; //Redirect the programs. startInfo.RedirectStandardError = true; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardInput = true; startInfo.ErrorDialog = false; var process = new Process(); process.EnableRaisingEvents = true; process.OutputDataReceived += (sender, args) => DataRecieved(args,false); process.ErrorDataReceived += (sender, args) => DataRecieved(args,true); process.StartInfo = startInfo; process.Exited += (sender, args) => ProcessClosed(process); TraceMessage(TraceLevel.Verbose, $"about to start process {nickname} @'{SERVER_executable}'"); if (!process.Start()) { throw new Exception($"cannot get the process {nickname} @'{SERVER_executable}' to start - returns false"); } OnEventOccurred(new ProcessHelperEvent(null, ProcessHelperEventType.ProcessStarted, nickname, process?.Id)); TraceMessage(TraceLevel.Info, $"process {nickname} started with pid {process.Id} @'{SERVER_executable}'"); //note: only works as long as your process actually creates a main window. while (process.MainWindowHandle == IntPtr.Zero) { System.Threading.Thread.Sleep(10); } // this hides the window without disable message pumping ShowWindow(process.MainWindowHandle, SW_HIDE); TraceMessage(TraceLevel.Verbose, $"window hidden for {nickname} pid {process.Id}"); currentProcess = process; } } public void Stop() { lock (processSync) { DisposeGuard(); if (currentProcess == null) { TraceMessage(TraceLevel.Warning, $"attempted to stop process {nickname} when no process is running - likely a race condition!"); return; } SendMessage(currentProcess.MainWindowHandle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); TraceMessage(TraceLevel.Verbose, $"sent WM_CLOSE to process {nickname} pid {currentProcess.Id}"); } } public void Kill() { lock (processSync) { DisposeGuard(); if (currentProcess == null) { TraceMessage(TraceLevel.Warning, $"attempted to KILL process {nickname} when no process is running - likely a race condition!"); return; } currentProcess.Kill(); TraceMessage(TraceLevel.Warning, $"KILLED process {nickname} pid {currentProcess.Id}"); currentProcess.Dispose(); currentProcess = null; } } public void Dispose() { lock (processSync) { if (!disposed && currentProcess != null) { TraceMessage(TraceLevel.Warning, $"KILLING {nickname} beccause you forgot to stop it before calling Dispose"); // welp, time waits for no one! currentProcess.Kill(); currentProcess = null; } else if (!disposed) { TraceMessage(TraceLevel.Verbose, $"diposed {nickname} gracefully, good job!"); } disposed = true; } } private void ProcessClosed(Process process) { lock (processSync) { OnEventOccurred(new ProcessHelperEvent(null, ProcessHelperEventType.ProcessStopped, nickname, process?.Id)); TraceMessage(TraceLevel.Info, $"process {nickname} pid {process?.Id} has closed, RIP"); process.Dispose(); if (currentProcess == process) { currentProcess = null; } } } private void DataRecieved(DataReceivedEventArgs args, bool wasError) { lock (processSync) { var type = wasError ? ProcessHelperEventType.ErrorMessage : ProcessHelperEventType.OutputMessage; OnEventOccurred(new ProcessHelperEvent(args.Data, type, nickname, currentProcess?.Id )); } } private void DisposeGuard([CallerMemberName] string callerName = "") { if (disposed) { throw new Exception($"attempted to call {callerName} after a dispose!!"); } } private void OnEventOccurred(ProcessHelperEvent args) { processEvents.Enqueue(args); EventOccured?.Invoke(this, args); } private static void TraceMessage(TraceLevel level, string message) { if (traceSwitch.Level >= level) { Trace.WriteLine(message, "Process"); } } } [/code] It is a quick linqpad script, but you can make it a regular console app by making Main() work. The for a 'test' is as follows: [img]http://i.imgur.com/mEomfpk.png[/img] Does this help at all? Basic idea is to use the same process method you created and wrap it into a pretty, non-blocking, thread safe bow. I imagine you'd simply enumerate the "ProcessEvents" for the log. Start and stop happens on one process. Each process/server is a single "ProcessHelper" instance. Note: you probably want to flush the "ProcessEvents" buffer so it is max 1000 lines or some such, likewise I don't like the event handler since they are easy to leak / mess up while plumbing (I'd prefer making it observable but might not be useful for you).[/QUOTE] Thank you, I have already implemented a class into Borealis that handles this code, and I will be testing it more tonight. I really, really appreciate how much work you have done, as well as how well commented the code is, explaining what everything does. This is a learning experience for me as well, so I like being able to read the logic of the code writer.
[QUOTE=VeXan;52545394]I've tried that specific snippet you posted there and nothing seemed to happen. Would you know why?[/QUOTE] Some other selector is overriding it. Do [code] .user_721043{ background: red !important; }[/code] [editline]6th August 2017[/editline] I've got two cpp files that both include the following header file: [code]#ifndef TOPDOWN_H_INCLUDED #define TOPDOWN_H_INCLUDED int cameraX; int cameraY; #endif // TOPDOWN_H_INCLUDED [/code] but I get a "multiple definition" error
Not sure if this is the right place, but I didn't feel like it warranted its own thread, so I'll post it here: I recently purchased a PTZ camera to add to my DIY home security. One of the features I like the most, is the camera can upload recordings to a FTP server, rather than needing to subscribe to a "cloud package" like most vendors require. My problem is the recordings have the extension .264, but they're not actually h264. I tried using VLC with various codex to view them, but it never worked. I contacted the vendor but they said I need to use the THEIR viewer and/or converter (.264 > .avi) software to watch the recordings because the file format is a "proprietary format customized for storage". Which is a bunch of horseshit because the converted .avi files are smaller than their original .264. Also, their viewer software is also a pile of crap and their conversion tool doesn't have any command line or batch mode, forcing me to convert a single file at a time. This is where I need some help. Best case scenario I'd like to be able to watch these recordings via an embedded video player, but I'd be happy to at least have a batch conversion tool. Problem here is I know nothing about converting video formats. Here's a link to a sample of [url=https://drive.google.com/open?id=0B1zkunfs5ZYQSGRjWVpRNkVEMWc]original and converted files[/url] I uploaded to compare, and a link to their [url=http://www.dericam.com/index/down/id/100.html]conversion tool[/url]. Anyone willing to take a crack at helping me with this?
[QUOTE=proboardslol;52545736]Some other selector is overriding it. Do [code] .user_721043{ background: red !important; }[/code] [/QUOTE] [QUOTE][IMG]http://i.imgur.com/4spsbD4.png[/IMG][/QUOTE] Heyy, check that out. Do you know how I can edit descriptions/name styles? I've tried a few different ways I thought would work but they never did. [editline]7th August 2017[/editline] Turned off my dark theme and now the shadow affects all aspects of the poster, including name. I just want to figure out how to change specific parts. [editline]7th August 2017[/editline] Looks like I'll have to edit a specific class (usertitle), but I'm not sure how to do that for a particular user. [editline]7th August 2017[/editline] Figured it out! Example I used: [code] .user_9477 .usertitle { text-shadow: 0 0 6px red; !important; } [/code] [QUOTE][IMG]http://i.imgur.com/3VBw7tL.png[/IMG][/QUOTE] [editline]7th August 2017[/editline] Figured out how to change titles too. I think it's more of a hack than anything, though. [QUOTE][IMG]http://i.imgur.com/H7CMbOd.png[/IMG][/QUOTE]
Hey guys, not exactly related to programming but I'm trying to find a specific post. A month or two ago I came across a really good post on a guy suggesting an education/work path that started at computer repairs and then going to tech support and finally skilled programming work in IT (or something along those lines, I think it was about becoming a full stack developper). It was a really long, detailed and insightful post and for the life of me I can't seem to find it again. I was really sure that it was in the [URL="https://facepunch.com/showthread.php?t=1511276"]General Adulthood[/URL] thread but it might have also been posted in another subforum. Does it ring a bell to anyone? It's kind of maddening as I can't find a trace of it anywhere. I really should have bookmarked it.
[QUOTE=StrawberryClock;52548740]Hey guys, not exactly related to programming but I'm trying to find a specific post. A month or two ago I came across a really good post on a guy suggesting an education/work path that started at computer repairs and then going to tech support and finally skilled programming work in IT (or something along those lines, I think it was about becoming a full stack developper). It was a really long, detailed and insightful post and for the life of me I can't seem to find it again. I was really sure that it was in the [URL="https://facepunch.com/showthread.php?t=1511276"]General Adulthood[/URL] thread but it might have also been posted in another subforum. Does it ring a bell to anyone? It's kind of maddening as I can't find a trace of it anywhere. I really should have bookmarked it.[/QUOTE] That's exactly what I did, but I don't remember writing a detailed and insightful post about it. ;)
Can anyone tell me if my implementation of the calculation for the center and radius of a circumsphere for a tetrahedron is correct? I'm basing my calculation off of this page from [URL="http://mathworld.wolfram.com/Circumsphere.html"]Wolfram[/URL] For my vector and matrix math library, I'm using GLM. Variables _p0 through _p3 are the 4 input vertex vector points. [code] float a = glm::determinant( mat4( vec4(_p0, 1), vec4(_p1, 1), vec4(_p2, 1), vec4(_p3, 1) ) ); float _p0_2_xyz = (_p0.x * _p0.x) + (_p0.y * _p0.y) + (_p0.z * _p0.z); float _p1_2_xyz = (_p1.x * _p1.x) + (_p1.y * _p1.y) + (_p1.z * _p1.z); float _p2_2_xyz = (_p2.x * _p2.x) + (_p2.y * _p2.y) + (_p2.z * _p2.z); float _p3_2_xyz = (_p3.x * _p3.x) + (_p3.y * _p3.y) + (_p3.z * _p3.z); float Dx = abs( glm::determinant( mat4( vec4( _p0_2_xyz, _p0.y, _p0.z, 1 ), vec4( _p1_2_xyz, _p1.y, _p1.z, 1 ), vec4( _p2_2_xyz, _p2.y, _p2.z, 1 ), vec4( _p3_2_xyz, _p3.y, _p3.z, 1 ) ) ) ); float Dy = -abs( glm::determinant( mat4( vec4( _p0_2_xyz, _p0.x, _p0.z, 1 ), vec4( _p1_2_xyz, _p1.x, _p1.z, 1 ), vec4( _p2_2_xyz, _p2.x, _p2.z, 1 ), vec4( _p3_2_xyz, _p3.x, _p3.z, 1 ) ) ) ); float Dz = abs( glm::determinant( mat4( vec4( _p0_2_xyz, _p0.x, _p0.y, 1 ), vec4( _p1_2_xyz, _p1.x, _p1.y, 1 ), vec4( _p2_2_xyz, _p2.x, _p2.y, 1 ), vec4( _p3_2_xyz, _p3.x, _p3.y, 1 ) ) ) ); float c = glm::determinant( mat4( vec4( _p0_2_xyz, _p0.x, _p0.y, _p0.z), vec4( _p1_2_xyz, _p1.x, _p1.y, _p1.z), vec4( _p2_2_xyz, _p2.x, _p2.y, _p2.z), vec4( _p3_2_xyz, _p3.x, _p3.y, _p3.z) ) ); vec3 center = vec3(Dx, Dy, Dz) / (2.0f * a); float radius = sqrt( (Dx * Dx) + (Dy * Dy) + (Dz * Dz) - 4.0f * a * c ) / (2.0f * abs(a)); [/code] I was a little bit confused when reading the formula.
How do save files work for big games like Half life 2? How do they keep the exact moment in a save file? Do they just dump the memory?
[QUOTE=proboardslol;52550955]How do save files work for big games like Half life 2? How do they keep the exact moment in a save file? Do they just dump the memory?[/QUOTE] Usually they don't just dump the memory - game state serialization can get quite complex especially when you have very hierarchical data, as the Source engine for example has (relatively deep class hierarchies, references by pointer etc). Some games serialize game state by visiting all actors or game objects or what have you and for each one recursively serializing their fields, which may or may not work in a generic fashion. They might also apply compression algorithms to reduce the final file size, only store relevant data (things that changed from defaults, etc).
[QUOTE=Karmah;52549343]Can anyone tell me if my implementation of the calculation for the center and radius of a circumsphere for a tetrahedron is correct? I'm basing my calculation off of this page from [URL="http://mathworld.wolfram.com/Circumsphere.html"]Wolfram[/URL] For my vector and matrix math library, I'm using GLM. Variables _p0 through _p3 are the 4 input vertex vector points. :snip: code snippet :snip: I was a little bit confused when reading the formula.[/QUOTE] After rigorous experimenting, stepping through my function, and visualizing the data, this math appears to be correct, unfortunately, meaning my long standing issue lies elsewhere in my algorithm.
I have a quick question for those of you experienced with bit-alignment. I've been using the same algorithm for years: [code](value + (alignment - (value % alignment)) % alignment)[/code] Nothing like good old modulo, right? Trying to calculate alignment in your head (or even in a calculator) seems like a daunting task. However, I always wondered if there was a much simpler way to do this. Using nothing more than the Windows calculator and a theory of mine, I narrowed it down to this: [code]((value + alignment) & -alignment)[/code] Which is technically a shorter version of this: [code]((value + alignment) & ~(alignment - 1))[/code] It behaves exactly as expected: [code]> ((3 + 8) & -8) > (11 & -8) > (0xB & 0xFFFFFFF8) >> = 8 (0x3 -> 0x8)[/code] [code]> ((3 + 4) & -4) > (7 & -4) > (0x7 & 0xFFFFFFFC) >> = 4 (0x3 -> 0x4)[/code] [code]> ((123 + 16) & -16) > (139 & -16) > (0x8B & 0xFFFFFFF0) >> = 128 (0x7B -> 0x80)[/code] Does anyone know if this is a shorter version of the modulo-based algorithm, or is this just similar yet error prone? I'd love to be able to update my code if it's actually correct. [b]EDIT:[/b] Ah yes, I just realized numbers that are already aligned to the requested alignment will be changed from their original value. The correct formula should be: [code]((value + (alignment - 1)) & -alignment)[/code] Still smaller than the modulo version and works just the same. Guess I should've posted this in the other thread since it's not really a question anymore :v:
Say I have a triangle that is randomly oriented in 3D space in any particular direction How can I compute a rotation matrix from it, such that I can use it to transform its own points into "triangle space"? Since all 3 points of a triangle define a plane, then their coordinates relative to the plane only change on 2 axes. In a nutshell I want to get the local coordinates of points on a triangle relative to its plane. I'm sure there is a way, but there are also infinite ways that the space could be rotated on the 3rd axis. I'm not sure how I would define which way is up relative to the plane.
[QUOTE=Karmah;52555262]Say I have a triangle that is randomly oriented in 3D space in any particular direction How can I compute a rotation matrix from it, such that I can use it to transform its own points into "triangle space"? Since all 3 points of a triangle define a plane, then their coordinates relative to the plane only change on 2 axes. In a nutshell I want to get the local coordinates of points on a triangle relative to its plane. I'm sure there is a way, but there are also infinite ways that the space could be rotated on the 3rd axis. I'm not sure how I would define which way is up relative to the plane.[/QUOTE] Sounds like this is what you need right? [url]https://gamedev.stackexchange.com/questions/68612/how-to-compute-tangent-and-bitangent-vectors[/url] A triangle can only have two normals, figuring out which way normal is correct can be done by following the winding order of a mesh. If you have just a triangle, either direction could be valid, whereas with a mesh normals facing inwards are usually wrong. But if your triangle normal is facing the wrong way, you can just reverse list of vertices it consists of and it'll point in the other direction.
[QUOTE=FalconKrunch;52555769]Sounds like this is what you need right? [url]https://gamedev.stackexchange.com/questions/68612/how-to-compute-tangent-and-bitangent-vectors[/url] A triangle can only have two normals, figuring out which way normal is correct can be done by following the winding order of a mesh. If you have just a triangle, either direction could be valid, whereas with a mesh normals facing inwards are usually wrong. But if your triangle normal is facing the wrong way, you can just reverse list of vertices it consists of and it'll point in the other direction.[/QUOTE] That's in a similar vein to what I need. I'm trying to generate UV coordinates from my geometry. I've generated a convex hull from a point cloud, and I'm looking for ways to uv wrap my triangles. If I could even get something as basic as each triangle wrapped between 0-1 that would be great, because then I can actually do some math in tangent space.
I'm trying to prank some friends by running a background application which would display some image over their screen from time to time (on top of all open tabs, possibly animated image). I'm thinking C# forms would be a good job for this, though I've never looked into that. Maybe anyone has some experience with this and could direct me to some resources?
Theoretical question: Could I run a script of some sort (JS script on Node.js server) that would crawl through website and convert every single image on it into hash string (say using blockhash-js) so even if image is different size - hash would be somewhat similar (can be easily compared) and then store that in database. So that later if I want to upload my own image - it would get converted into hash string as well and compare hash value of my uploaded image and those stored in DB already and that way see if that image ever existed on server? Would that kind of reverse image search work? (Talking about 4000-5000 images on small website).
Anyone who has recommendations for documentation? - I mean like, of course editor works - but documentation of API's etc? I'm especially interested in solutions that can be self-hosted.
So I'm really bad with Apache and all that fun stuff. I'm trying to use WSGI to host two flask apps on an Ubuntu server. So far I've followed a tutorial to set it up but I don't think I'm getting any results. Here is my .wsgi for the first app: [code] #!/usr/bin/python import sys import logging logging.basicConfig(stream=sys.stderr) sys.path.insert(0,"/var/www/Simon/") from Simon import simon as application application.secret_key = ... activate_this = '/var/www/Simon/Simon/bin/activate.py' execfile(activate_this, dict(__file__=activate_this)) [/code] It's supposed to run inside a virtual env obviously. Next is my app's .conf in /etc/apache2/sites-available [code] <VirtualHost *:80> ServerName glencoverx.com ServerAdmin jp@glencoverx.com WSGIScriptAlias / /var/www/Simon/Simon.wsgi <Directory /var/www/Simon> Require all granted </Directory> Alias /static /var/www/Simon/static <Directory /var/www/Simon/static/> Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> [/code] Upon running curl, I just get a 500 error. I have no idea what I'm doing.
[QUOTE=proboardslol;52550955]How do save files work for big games like Half life 2? How do they keep the exact moment in a save file? Do they just dump the memory?[/QUOTE] Not sure how Source works but Half-Life's looks simple enough (or at least the game code part of it does). I assume when you hit save the engine iterates through all entities and you can see in the game code each entity has some configuration data that returns details about the state of each entity. When you reload a game the each entity is recreated and its internal state is set to what was saved from the game code. That way each entity ends up in the same spot, with the same health, at the same point in the same animation etc. [QUOTE=Killervalon;52559413]Anyone who has recommendations for documentation? - I mean like, of course editor works - but documentation of API's etc? I'm especially interested in solutions that can be self-hosted.[/QUOTE] [url]https://swagger.io/[/url] for documenting APIs. You may want to use a library to generate it though. [QUOTE=Adelle Zhu;52563388]So I'm really bad with Apache and all that fun stuff. I'm trying to use WSGI to host two flask apps on an Ubuntu server. So far I've followed a tutorial to set it up but I don't think I'm getting any results. Here is my .wsgi for the first app: [code] #!/usr/bin/python import sys import logging logging.basicConfig(stream=sys.stderr) sys.path.insert(0,"/var/www/Simon/") from Simon import simon as application application.secret_key = ... activate_this = '/var/www/Simon/Simon/bin/activate.py' execfile(activate_this, dict(__file__=activate_this)) [/code] It's supposed to run inside a virtual env obviously. Next is my app's .conf in /etc/apache2/sites-available [code] <VirtualHost *:80> ServerName glencoverx.com ServerAdmin jp@glencoverx.com WSGIScriptAlias / /var/www/Simon/Simon.wsgi <Directory /var/www/Simon> Require all granted </Directory> Alias /static /var/www/Simon/static <Directory /var/www/Simon/static/> Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> [/code] Upon running curl, I just get a 500 error. I have no idea what I'm doing.[/QUOTE] What do the Apache error logs say?
Open-Source/github question. What would be a way of having assets I paid for but still having an open source repository? Maybe open source the code but not the whole repo?
Sorry, you need to Log In to post a reply to this thread.