Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Jabor
Jul 16, 2010

#1 Loser at SpaceChem
If all your plugins are going to be doing is parsing result data and determine what persistent-state updates are needed, then it really sounds like the best solution would be to just chuck a small scripting language in there and use that.

Adbot
ADBOT LOVES YOU

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Jabor posted:

If all your plugins are going to be doing is parsing result data and determine what persistent-state updates are needed, then it really sounds like the best solution would be to just chuck a small scripting language in there and use that.
The persistent states have a 'live' version in the C code too, and the structures involved are of horrifying mutable shapes, it would be a nightmare trying to make all the interfaces that would be involved to give the scripting language access to flexible enough functionality to do that - and make those interfaces flexible enough that they wouldn't end up needing to be changed too.

You're probably right that it would be the best solution, but as a one-man devteam I want to strike a balance between 'best' and 'quickest'.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I guess I might just be underestimating how complex your persistence is, but surely it shouldn't be too complex to implement a comprehensive interface?

I mean, what possible outcomes are there from a game? The user gained/lost {x} in-game currency? The user found {x}, {y} and {z} items? The user's rank changed by {x} points?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Jabor posted:

I guess I might just be underestimating how complex your persistence is, but surely it shouldn't be too complex to implement a comprehensive interface?

I mean, what possible outcomes are there from a game? The user gained/lost {x} in-game currency? The user found {x}, {y} and {z} items? The user's rank changed by {x} points?
Well there's one that I hadn't already considered for a start - bonus items. Some of which may have characteristics that don't already exist, so now the interface needs to already have had a way of adding items that I didn't think of with characteristics that I didn't think of ... and I have to write it for a scripting language I don't already know so I'd also have to learn it and get it all set up and working and integrated into my already-extant and working server.

And on the input side, I'm not sure how easy it would be for a Lua function to handle "here is a wad of data in the form of C structures serialized inside each other with the values in network byte order." (The interface can't handle converting this into something better because the structures are defined by the minigame, which doesn't yet exist.)

Again, I'm not saying it's impossible, just it seems like it'd be a lot more work for very little extra benefit.

Other things a game's scoring might want to do - refer to scores from other related games, access data about a guild/team of some sort, check how much you've played recently, assign achievements.

roomforthetuna fucked around with this message at 07:19 on Nov 9, 2010

ToxicFrog
Apr 26, 2008


roomforthetuna posted:

And on the input side, I'm not sure how easy it would be for a Lua function to handle "here is a wad of data in the form of C structures serialized inside each other with the values in network byte order." (The interface can't handle converting this into something better because the structures are defined by the minigame, which doesn't yet exist.)

There's at least three Lua libraries (struct, vstruct, and lpack) for packing and unpacking binary data, but at that point, why not just store the structures in Lua entirely and examine them from C as needed? This has the advantage of letting you easily determine their shape at runtime.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

roomforthetuna posted:

Some of which may have characteristics that don't already exist, so now the interface needs to already have had a way of adding items that I didn't think of with characteristics that I didn't think of ...
This isn't necessary unless you're going so far as to be generating new, unique items while the game is running. If you're just adding previously-unthought-of items when you add a new plugin or update one, this can be handled by manually updating the items database when you do that.

quote:

Other things a game's scoring might want to do - refer to scores from other related games, access data about a guild/team of some sort, check how much you've played recently, assign achievements.
Achievements are something "obvious" the API should handle, everything else can all be handled by giving plugin processes read access on the backend. Not everything needs to go through the core server.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

ToxicFrog posted:

There's at least three Lua libraries (struct, vstruct, and lpack) for packing and unpacking binary data, but at that point, why not just store the structures in Lua entirely and examine them from C as needed? This has the advantage of letting you easily determine their shape at runtime.
If I was going that far I might as well be rewriting the entire server in Lua, surely? The nesty structures are my network "packets".

quote:

This isn't necessary unless you're going so far as to be generating new, unique items while the game is running. If you're just adding previously-unthought-of items when you add a new plugin or update one, this can be handled by manually updating the items database when you do that.
I'm going to be adding a new plugin or updating one while the game is running! I'm aiming for pretty much never having to shut the server down (only some sort of additional meta-game function would require a restart, I don't want to restart for additional items, mini-games, changes to the meta-world, anything that's likely to happen often.) And this is already working.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

roomforthetuna posted:

I'm going to be adding a new plugin or updating one while the game is running!
Yep, and you can manually update the database when you do that. The only case in which you wouldn't be able to do that is if the plugins themselves generated arbitrary unique items on their own.

Demerzel
Sep 11, 2001

Only the spergiest will do.
I am posting this as a last resort because it's insanity how much time I've spent on it and now it's become one of those problems I MUST SOLVE.

Scenario: ISO-C, stdin parsing.

Some thing simple like fgets or even getch in windows, right? No sweat! Yep, typed to it works fine. Moving on..

Oh wait it's not responding now that it's a child process with stdin redirected. That's odd, it's stopping at 700ish characters and just freezing. Maybe if I just setvbuf stdin to 4096 or redirect to a buffer or do 1 char at a time or...

3 days later I've tried every drat thing i can think of and that google can throw at me.
The ONLY thing that will get it to work on linux OR windows (and i only have windows to test with) is by directly using GetStdHandle(STD_INPUT_HANDLE) (and then fread) which is proprietary windows. I also know it's not working in linux but can't really test there.

Code can be any loop involving fgets,fgetc,getch,getchar,so on on stdin - fgets freezes completely but I can fetch one char at a time. fflush while not standard does not seem to do anything other than break it.

I managed to attach to the running process and found that the buffer was getting data and I think windows is locking stdin like it would a file, which would explain the broken pipe - but I have no idea how to stop that in a portable solution (this is actually going to linux)

I am tempted to just upgrade it to cpp and use cin but now it's a matter of learning what is wrong and I can't resist. So if anyone has any suggestions I would love to hear them - it can be c89 or c99 i'm just letting you know it's in c89.

If anyone can help me out I've been googling +c -perl -python -"c++" +stdin <blah> forever and I've only found the one fread solution which is windows only, it would be a huge timesaver!

Demerzel fucked around with this message at 02:56 on Nov 10, 2010

Vanadium
Jan 8, 2005

Is there any way you can post something that compiles and exhibits the problem? :shobon:

If I understand correctly, a child process with stdin redirected hangs reading more than ~700 characters? But not with fread?

Demerzel
Sep 11, 2001

Only the spergiest will do.

Vanadium posted:

Is there any way you can post something that compiles and exhibits the problem? :shobon:

If I understand correctly, a child process with stdin redirected hangs reading more than ~700 characters? But not with fread?

Well what I was using was essentially a loop that read one char at a time (since fgets completely froze it) using the 'stdin' handle. It's really difficult to reproduce because piping a file to it works fine since it's a steady stream, as does typing to it - it's the generated on demand parent process that messes it up.

here is my quick and dirty code to read one char/line at a time after fgets died on launch: http://pastebin.com/E39KjpDs

What's sad is if i include <iostream> and convert the entire thing to cpp to add one line:
code:
cin.getline(io_input)
which is even a char *, it works.

what DOES work (in windows) is the get handle STD_INPUT_HANDLE(DWORD -12) and freading it

what happens with the above is it dies after about 700chars which i know because it's spitting back HI + whatever it's collected, i /think/ it's because windows locks the 'file' so the parent process can't write to it while reading it via getchar()

note i've tried fgetc and __getch and every other iteration too

Demerzel fucked around with this message at 07:48 on Nov 10, 2010

Pooball
Sep 21, 2005
Warm and squishy.

Demerzel posted:

Oh wait it's not responding now that it's a child process with stdin redirected. That's odd, it's stopping at 700ish characters and just freezing. Maybe if I just setvbuf stdin to 4096 or redirect to a buffer or do 1 char at a time or...

To diagnose problems you should turn off buffering and do everything yourself. Or just use the low level call "_read" instead of fread. This is also portable.

I am fairly sure that other APIs are no more powerful than _read. You can get weird behavior because the way you read data can affect the way the process on the other end of the pipe writes data. When you say fgets hangs, are you sure the writer process has written a newline?

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
Yeah, your loop is wrong. If the process doesn't send a '\n' when it's done, you'll loop forever. You need to check for EOF when you call getchar() (and, assuming you're calling it in a loop, NULL when you call fgets()).

Demerzel
Sep 11, 2001

Only the spergiest will do.

Pooball posted:

To diagnose problems you should turn off buffering and do everything yourself. Or just use the low level call "_read" instead of fread. This is also portable.

I am fairly sure that other APIs are no more powerful than _read. You can get weird behavior because the way you read data can affect the way the process on the other end of the pipe writes data. When you say fgets hangs, are you sure the writer process has written a newline?

Alright, that brings up a question then - how exactly do I turn off buffering? The ones I've seen look like this:

setvbuf(stdin,(void*)NULL,_IOFNBF,0) also with just NULL or seen examples with _IOFBF but still 0 -- but my local compiler(VC, i know!) throws an exception on the 0 - though gcc might work. I also tried setting up buffering directly to the char* itself but that didn't work either. I also tried to redirect the BUFSIZ macro to 4096. However it's very possible I'm doing/thinking of it wrong.

Re: fgets/newlines, yes I know exactly what it is sending - it's pure lines of approx 16-24 chars terminated by only one \n (as opposed to \r\n)

The loop was a quick and dirty, I know it's not great - fgets was using a 128 char limit, if i was serious about it I'd at least be checking for 128. Also how would I check for EOF in stdin, would it even exist? I already tried using the standard int c, if c == EOF / FEOF and it never tripped, was in fact one of the first things I tried.

I"ll take a look at __read -- I am curious how the hell std::cin.getline() works perfectly whether compiled with gcc or vc to be honest.

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
For getchar():
code:
char *next_char = io_input;
int c;
while ((c = getchar()) != EOF){
  *next_char = c;
  ++next_char;
  if (next_char == end_of_io_input_buffer || c == '\n') return;
}

Demerzel posted:

However it's very possible I'm doing/thinking of it wrong.
Yeah, you're kind of flipping out a little bit and assuming that the C runtime is broken, when it's much more likely that your code just has a typo or something like that. What does your fgets() version look like? What characters are sent by the parent process at the 700 mark? What does the parent process's code look like?

Demerzel
Sep 11, 2001

Only the spergiest will do.

Mustach posted:

Yeah, you're kind of flipping out a little bit and assuming that the C runtime is broken, when it's much more likely that your code just has a typo or something like that. What does your fgets() version look like? What characters are sent by the parent process at the 700 mark? What does the parent process's code look like?

You're missing the point of the code I posted - that is one of a dozen methods I've tried, I'm well aware it's not safe or optimal, it's just a hack to try to make it past whatever breaking point and have it spit out what it's got so far since I know exactly what input is going to it.

The parent process code is not written by me - it's python and I can get the source but any other language (including C++) has no issue handling the redirected stdin.

The rest of the code is irrelevant to this issue since I took it completely out while working on this problem and still have it, essentially what it does is parse the lines, looking for a go\n to indicate that input is done, then parses it and sends a go\n back.

The character at the 807 mark that broke it last time was just a generic ascii digit. It does break at the same point regardless of what method I use to pull 1 char at a time, if I use fgets it never gets to the point of being able to fprintf(stderr,io_output). If I substitute other data it breaks somewhere between 7-900 chars, always at the same point for that particular dataset but not particular to a char or number of chars.

I'm not assuming the C runtime is broken, I'm assuming that there's something I'm missing here, it's uncommon enough that I am finding tons of one-off stuff but nothing directly related, except a few links to an msdn article that had the working windows code.

The fact that I literally can replace io_receiveLine() with std::cin.getline(io_output) and have it work perfectly tells me there is /something/ i need to do that cin does that fgets etc does not. What that is I have no idea.

Demerzel fucked around with this message at 16:29 on Nov 10, 2010

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

Demerzel posted:

You're missing the point of the code I posted - that is one of a dozen methods I've tried, I'm well aware it's not safe or optimal, …
Then how about you show us the actual implementation with fgets() that want to use, instead of some hack that you typed out in desperation? Everyone's just going to guess until you post the code.

Demerzel
Sep 11, 2001

Only the spergiest will do.

Mustach posted:

Then how about you show us the actual implementation with fgets() that want to use, instead of some hack that you typed out in desperation? Everyone's just going to guess until you post the code.


code:

char io_stdin[128];
int alldone = 0;

int main() 
{
  while(alldone == 0)
  {
    io_receiveLine();
    printf("go\n");
  }
}

void io_receiveLine()
{
  int inputDone = 0;
  char* retval;
  memset(io_stdin,0,sizeof(io_stdin));
  while(inputDone == 0)
  {
    retval = fgets(io_stdin, 128, stdin);
    if(retval == io_stdin)
    {
      inputDone = io_parseLine();
    }
  }
}

const int io_parseLine()
{
  if(io_stdin[0] == 'g'){ return 1; }
  return 0;
}
EDIT: I have put in a dirty dirty hack using scanf and it works too.

Demerzel fucked around with this message at 18:06 on Nov 10, 2010

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Demerzel posted:

code:
  while(inputDone == 0)
  {
    retval = fgets(io_stdin, 128, stdin);
    if(retval == io_stdin)
    {
      inputDone = io_parseLine();
    }
  }
Are you sure it's actually freezing on the fgets, not being stuck in the inputDone loop while fgets repeatedly returns NULL?

Demerzel
Sep 11, 2001

Only the spergiest will do.

roomforthetuna posted:

Are you sure it's actually freezing on the fgets, not being stuck in the inputDone loop while fgets repeatedly returns NULL?

No I'm not at all sure where exactly it's freezing. I'm basing the idea that it's freezing on fgets is because when I stick a fprintf(stderr,"output: %s",io_stdin); after it nothing ever appears vs with fgetc or getchar I do get input back.

I assumed that if it returned null (ie not a pointer to io_stdin) it would loop back, if that's wrong that definitely be an issue.

Actually one thing I'm considering is the fgets is specifically looking for '\r\n' since I'm on windows, which doesn't exist. However, the same code deployed to linux has the same issue.

scanf however does fix the issue, but I'm not sure how not to have to hack in the \n since it goes to spaces, how would you set up a scanf expression to mimic the behavior of fgets?

vvv correct vvv

Demerzel fucked around with this message at 20:15 on Nov 10, 2010

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Demerzel posted:

No I'm not at all sure where exactly it's freezing. I'm basing the idea that it's freezing on fgets is because when I stick a fprintf(stderr,"output: %s",io_stdin); after it nothing ever appears vs with fgetc or getchar I do get input back.

I assumed that if it returned null (ie not a pointer to io_stdin) it would loop back, if that's wrong that definitely be an issue.
That sounds reasonable then. But wait, nothing ever appears? As in, fgets doesn't return even once?

A Bloody Crowbar
May 9, 2009

So, I've recently decided to roll up my sleeves and start reading some beginner C++ manuals. I've come across something that I'm having a bit of trouble wrapping my head around (and sorry if this is kind of stupid question, I'm very much interested in the whys of things) but it says something like:

"assuming two boolean values p and q, a logical XOR is constructed as such:"
code:
(p || q) && !(p && q) 
The book attempts to explain how this works but I really don't think it phrases it very well because I'm still having trouble reasoning why it works this way.

p is ORed with q which means if either one is true, then the operation is true (in a truth table three out of four possibilities are then true). Then p and q are ANDed with a NOT operator in front of the operation, so the time when the operation would equate to true is when p and q are not both true (which would be three out of four possibilities again). This is ANDed with the initial OR operation to make an XOR (in which one and only one operand is true)? I'm not getting it.

If anyone could maybe explain the logic behind it to me better it would be appreciated... I feel kind of dumb asking something like this!

A Bloody Crowbar fucked around with this message at 20:49 on Nov 10, 2010

Vanadium
Jan 8, 2005

"one and only one operand is true" is the same as "at least one is true, but not both". "at least one is true" is p || q, and "not both" is !(p && q).

A Bloody Crowbar
May 9, 2009

Vanadium posted:

"one and only one operand is true" is the same as "at least one is true, but not both". "at least one is true" is p || q, and "not both" is !(p && q).
OH. drat.
Yeah that makes sense. For some reason I wasn't thinking that this would eliminate both operands being true equating a typical or operation to true so it was confusing me as to why you would do this. stupid :words:

That Turkey Story
Mar 30, 2003

XOR is just bitwise !=

Mopp
Oct 29, 2004

I'm getting this error: "Game.h:39: error: expected `;' f?re symbolen '('"
and this is my game class:

code:
class Game {
 public:
  SDL_Surface* load_image(std::string);
  Game();
  ~Game();
  void run();
  bool init(); 
  // void handle_input();
  bool load_files();
  void update_on_screen();
  void load_game();
  void clean_up();
  Player player;
};
row 39 is the third from the top, the load_image function. I have no idea why g++ is complaining about this error. Anyone that could give me a tip?

Zerf
Dec 17, 2004

I miss you, sandman

Mopp posted:

I'm getting this error: "Game.h:39: error: expected `;' f?re symbolen '('"
and this is my game class:

code:
class Game {
 public:
  SDL_Surface* load_image(std::string);
  Game();
  ~Game();
  void run();
  bool init(); 
  // void handle_input();
  bool load_files();
  void update_on_screen();
  void load_game();
  void clean_up();
  Player player;
};
row 39 is the third from the top, the load_image function. I have no idea why g++ is complaining about this error. Anyone that could give me a tip?

You fail to include a header file declaring SDL_Surface/you are not forward declaring SDL_Surface/you include a broken header file?

Mopp
Oct 29, 2004

Zerf posted:

You fail to include a header file declaring SDL_Surface/you are not forward declaring SDL_Surface/you include a broken header file?

well, no. I copied the entire file here: http://pastebin.com/w5ELYspc

it complains at the SDL_Surface* load_image(std::string); and the only error message i'm getting is Game.h:50: error: expected `;' f?re symbolen '('

Vanadium
Jan 8, 2005

Mopp posted:

well, no. I copied the entire file here: http://pastebin.com/w5ELYspc

it complains at the SDL_Surface* load_image(std::string); and the only error message i'm getting is Game.h:50: error: expected `;' f?re symbolen '('
You are missing <string>.

Demerzel
Sep 11, 2001

Only the spergiest will do.
Well, I solved it. Just for anyone who randomly comes across the same problem the only way I could get it to work was to only use functions that do not specify stdin/stdout.

So I ended up with a getchar loop and a putchar loop followed by fflush.

wlokos
Nov 12, 2007

...
I am working on another basic homework assignment thing and I'm having a weird problem, and I can't figure out what is causing it. A small note is that the class (which is really a free online class thing, they filmed a computer science course at a college and put it up) uses its own library that contains the command GetFloat, which I don't think is a normal C command. It gets a float, which is pretty obvious.

Anyway, the code up to the point of issue:

code:
#include <stdio.h>
#include <cs50.h>

int
main(int argc, char *argv[])
{
     float x = 0;
     int y = 0;
     do
     {
         printf("How much change do you need?\n");
         x = GetFloat(); // prompts user for a number and stores it as float X
     }
     while (x<0); //number has to be positive for reasons I won't bother to explain
     y = x * 100;
     printf("y is %d, x is %f\n", y, x);
}
The prompt would look something like this:

code:
How much change do you need?
.49
y is 49, x is .490000
The issue is, for some reason, if I enter the number .5, .51, or .52 at the prompt, it doesn't give me the right number. Instead, it would look like this:

code:
How much change do you need?
.51
y is 50, x is .510000
I'm assuming that this is some kind of rounding issue, perhaps I'm misunderstanding something about how floats/ints work? Any help on how I could fix that issue would be really appreciated.

pseudorandom name
May 6, 2007

nevermind

pseudorandom name fucked around with this message at 06:31 on Nov 11, 2010

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

wlokos posted:

I'm assuming that this is some kind of rounding issue, perhaps I'm misunderstanding something about how floats/ints work? Any help on how I could fix that issue would be really appreciated.

Yep. 51/100ths can't be expressed in closed form as a binary number, so the float is inevitably going to be slightly smaller or larger than the true value, and multiplying it by 100 won't necessarily give you exactly the original numerator. The "right" solution is to not read it in as a float in the first place; if that's not possible/worthwhile, just add a small number before rounding to make sure that you get something slightly larger than the nearest integer.

wlokos
Nov 12, 2007

...
If I didn't want to read it as a float, what would I read it as? I thought that ints couldn't hold tenths/hundrenths of a number, so that wouldn't work either if the user was going to enter in anything other than an integer... or is that not right?

BigRedDot
Mar 6, 2008

wlokos posted:

If I didn't want to read it as a float, what would I read it as? I thought that ints couldn't hold tenths/hundrenths of a number, so that wouldn't work either if the user was going to enter in anything other than an integer... or is that not right?

$0.51 (float) is also 51 cents (integer), for one example. You just need to change your internal units, converting the user input by hand, if that is an option.

Vanadium
Jan 8, 2005

People tend to yell at you for using floating point numbers/operations (which are necessarily imprecise) for currencies anyway, and you just found out why!

POKEMAN SAM
Jul 8, 2004

Vanadium posted:

People tend to yell at you for using floating point numbers/operations (which are necessarily imprecise) for currencies anyway, and you just found out why!

Yeah, he got off pretty easy, didn't he?

evensevenone
May 12, 2001
Glass is a solid.

Ugg boots posted:

Yeah, he got off pretty easy, didn't he?

if you're just learning its one thing, if you're programming bank software it's kind of another thing.

For that matter, bad beginner CS classes seem to love to use floats for currency because bad professors think their students are idiots and won't be able to comprehend any other use for decimal numbers. whatever instructor made that assignment should be run up a flagpole, not their students.


edit: Lol it's Harvard. What a bunch of tools.

https://www.cs50.net/psets/1/pset1.pdf

evensevenone fucked around with this message at 20:45 on Nov 11, 2010

wlokos
Nov 12, 2007

...

BigRedDot posted:

$0.51 (float) is also 51 cents (integer), for one example. You just need to change your internal units, converting the user input by hand, if that is an option.

How would I go about "converting the user input by hand"? I don't know of any way to make a float into an int (or otherwise handle the input properly) other than the way that I did it. I am extremely new to programming so I apologize for being slow!

and thanks to everybody for the help, I really appreciate it.

Adbot
ADBOT LOVES YOU

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

wlokos posted:

How would I go about "converting the user input by hand"? I don't know of any way to make a float into an int (or otherwise handle the input properly) other than the way that I did it. I am extremely new to programming so I apologize for being slow!

and thanks to everybody for the help, I really appreciate it.
The user input isn't a float, it's a string - you'd have to parse the string into two integers, instead of using the GetFloat function.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply