19 Nov, 2012, Liko wrote in the 1st comment:
Votes: 0
Hello again! I've ran into another problem with socketing. I have it completely working, but when you try to load the mud with existing .obj files the mud crashes. I didn't run into this issue, because I had no .obj files. When you create new obj or .obj file it saves and loads correctly.

Here is the exact error I get:

Nov 15 01:04:15 :: SYSERR: Format error in (f): object #1, after numeric constants
…expecting 'E', 'A', 'B', '$', or next object number


So this error made me believe its in this function:

/* read all objects from obj file; generate index and prototypes */
char *parse_object(FILE *obj_f, int nr)
{
static int i = 0;
static char line[READ_SIZE];
int t[10], j, retval;
char *tmpptr, buf2[128], f1[READ_SIZE], f2[READ_SIZE], f3[READ_SIZE], f4[READ_SIZE];
char f5[READ_SIZE], f6[READ_SIZE], f7[READ_SIZE], f8[READ_SIZE];
char f9[READ_SIZE], f10[READ_SIZE], f11[READ_SIZE], f12[READ_SIZE];
struct extra_descr_data *new_descr;

obj_index[i].vnum = nr;
obj_index[i].number = 0;
obj_index[i].func = NULL;

clear_object(obj_proto + i);
obj_proto[i].item_number = i;

sprintf(buf2, "object #%d", nr); /* sprintf: OK (for 'buf2 >= 19') */

/* string data */
if ((obj_proto[i].name = fread_string(obj_f, buf2)) == NULL) {
log("SYSERR: Null obj name or format error at or near %s", buf2);
exit(1);
}
tmpptr = obj_proto[i].short_description = fread_string(obj_f, buf2);
if (tmpptr && *tmpptr)
if (!str_cmp(fname(tmpptr), "a") || !str_cmp(fname(tmpptr), "an") ||
!str_cmp(fname(tmpptr), "the"))
*tmpptr = LOWER(*tmpptr);

tmpptr = obj_proto[i].description = fread_string(obj_f, buf2);
if (tmpptr && *tmpptr)
CAP(tmpptr);
obj_proto[i].action_description = fread_string(obj_f, buf2);

/* numeric data */
if (!get_line(obj_f, line)) {
log("SYSERR: Expecting first numeric line of %s, but file ended!", buf2);
exit(1);
}

if (((retval = sscanf(line, " %d %s %s %s %s %s %s %s %s %s %s %s %s", t, f1, f2, f3,
f4, f5, f6, f7, f8, f9, f10, f11, f12)) == 4) && (bitwarning == TRUE)) {
/* Let's make the implementor read some, before converting his world files. */
log("WARNING: Conventional object files detected. Please see config.c.");
exit(1);
} else if (((retval == 4) || (retval == 3)) && (bitwarning == FALSE)) {

if (retval == 3)
t[3] = 0;
else if (retval == 4)
t[3] = asciiflag_conv_aff(f3);

log("Converting object #%d to 128bits..", nr);
GET_OBJ_EXTRA(obj_proto + i)[0] = asciiflag_conv(f1);
GET_OBJ_EXTRA(obj_proto + i)[1] = 0;
GET_OBJ_EXTRA(obj_proto + i)[2] = 0;
GET_OBJ_EXTRA(obj_proto + i)[3] = 0;
GET_OBJ_WEAR(obj_proto + i)[0] = asciiflag_conv(f2);
GET_OBJ_WEAR(obj_proto + i)[1] = 0;
GET_OBJ_WEAR(obj_proto + i)[2] = 0;
GET_OBJ_WEAR(obj_proto + i)[3] = 0;
GET_OBJ_PERM(obj_proto + i)[0] = asciiflag_conv_aff(f3);
GET_OBJ_PERM(obj_proto + i)[1] = 0;
GET_OBJ_PERM(obj_proto + i)[2] = 0;
GET_OBJ_PERM(obj_proto + i)[3] = 0;

if(bitsavetodisk) {
add_to_save_list(zone_table[real_zone_by_thing(nr)].number, 1);
converting = TRUE;
}

log(" done.");
} else if (retval == 13) {

GET_OBJ_EXTRA(obj_proto + i)[0] = asciiflag_conv(f1);
GET_OBJ_EXTRA(obj_proto + i)[1] = asciiflag_conv(f2);
GET_OBJ_EXTRA(obj_proto + i)[2] = asciiflag_conv(f3);
GET_OBJ_EXTRA(obj_proto + i)[3] = asciiflag_conv(f4);
GET_OBJ_WEAR(obj_proto + i)[0] = asciiflag_conv(f5);
GET_OBJ_WEAR(obj_proto + i)[1] = asciiflag_conv(f6);
GET_OBJ_WEAR(obj_proto + i)[2] = asciiflag_conv(f7);
GET_OBJ_WEAR(obj_proto + i)[3] = asciiflag_conv(f8);
GET_OBJ_PERM(obj_proto + i)[0] = asciiflag_conv(f9);
GET_OBJ_PERM(obj_proto + i)[1] = asciiflag_conv(f10);
GET_OBJ_PERM(obj_proto + i)[2] = asciiflag_conv(f11);
GET_OBJ_PERM(obj_proto + i)[3] = asciiflag_conv(f12);

} else {
log("SYSERR: Format error in first numeric line (expecting 13 args, got %d), %s", retval, buf2);
exit(1);
}

/* Object flags checked in check_object(). */
GET_OBJ_TYPE(obj_proto + i) = t[0];

if (!get_line(obj_f, line)) {
log("SYSERR: Expecting second numeric line of %s, but file ended!", buf2);
exit(1);
}
if ((retval = sscanf(line, "%d %d %d %d", t, t + 1, t + 2, t + 3)) != 4) {
log("SYSERR: Format error in second numeric line (expecting 4 args, got %d), %s", retval, buf2);
exit(1);
}
GET_OBJ_VAL(obj_proto + i, 0) = t[0];
GET_OBJ_VAL(obj_proto + i, 1) = t[1];
GET_OBJ_VAL(obj_proto + i, 2) = t[2];
GET_OBJ_VAL(obj_proto + i, 3) = t[3];

if (!get_line(obj_f, line)) {
log("SYSERR: Expecting third numeric line of %s, but file ended!", buf2);
exit(1);
}
if ((retval = sscanf(line, "%d %d %d %d %d", t, t + 1, t + 2, t + 3, t + 4)) != 5) {
if (retval == 3) {
t[3] = 0;
t[4] = 0;
} else if (retval == 4)
t[4] = 0;
else {
log("SYSERR: Format error in third numeric line (expecting 5 args, got %d), %s", retval, buf2);
exit(1);
}
}

GET_OBJ_WEIGHT(obj_proto + i) = t[0];
GET_OBJ_COST(obj_proto + i) = t[1];
GET_OBJ_RENT(obj_proto + i) = t[2];
GET_OBJ_LEVEL(obj_proto + i) = t[3];
GET_OBJ_TIMER(obj_proto + i) = t[4];

if (!get_line(obj_f, line)) {
log("SYSERR: Expecting fourth numeric line of %s, but file ended!", buf2);
exit(1);
}
if ((retval = sscanf(line, "%d %d", t, t + 1)) != 2) {
if(retval == 0) {
t[0] = 0;
t[1] = 0;
} else if (retval == 1)
t[1] = 0;
else {
log("SYSERR: Format error in fourth numeric line (expecting 2 args, got %d), %s", retval, buf2);
exit(1);
}
}
GET_OBJ_SOCKET_MIN(obj_proto + i) = t[0];
GET_OBJ_SOCKET_MAX(obj_proto + i) = t[1];

obj_proto[i].sitting_here = NULL;

/* check to make sure that weight of containers exceeds curr. quantity */
if (GET_OBJ_TYPE(obj_proto + i) == ITEM_DRINKCON ||
GET_OBJ_TYPE(obj_proto + i) == ITEM_FOUNTAIN) {
if (GET_OBJ_WEIGHT(obj_proto + i) < GET_OBJ_VAL(obj_proto + i, 1) && CAN_WEAR(obj_proto + i, ITEM_WEAR_TAKE))
GET_OBJ_WEIGHT(obj_proto + i) = GET_OBJ_VAL(obj_proto + i, 1) + 5;
}

/* extra descriptions and affect fields */
for (j = 0; j < MAX_OBJ_AFFECT; j++) {
obj_proto[i].affected[j].location = APPLY_NONE;
obj_proto[i].affected[j].modifier = 0;
}
/*Bonus for sockets */
for (j= 0; j < MAX_SOCKET_AFFECT; j++) {
obj_proto[i].bonus[j].location = SOCKET_NONE;
obj_proto[i].bonus[j].modifier = 0;
}

strcat(buf2, ", after numeric constants\n" /* strcat: OK (for 'buf2 >= 87') */
"…expecting 'E', 'A', 'B', '$', or next object number");
j = 0;

for (;;) {
if (!get_line(obj_f, line)) {
log("SYSERR: Format error in %s", buf2);
exit(1);
}
switch (*line) {
case 'E':
CREATE(new_descr, struct extra_descr_data, 1);
new_descr->keyword = fread_string(obj_f, buf2);
new_descr->description = fread_string(obj_f, buf2);
new_descr->next = obj_proto[i].ex_description;
obj_proto[i].ex_description = new_descr;
break;
case 'A':
if (j >= MAX_OBJ_AFFECT) {
log("SYSERR: Too many A fields (%d max), %s", MAX_OBJ_AFFECT, buf2);
exit(1);
}
if (!get_line(obj_f, line)) {
log("SYSERR: Format error in 'A' field, %s\n"
"…expecting 2 numeric constants but file ended!", buf2);
exit(1);
}

if ((retval = sscanf(line, " %d %d ", t, t + 1)) != 2) {
log("SYSERR: Format error in 'A' field, %s\n"
"…expecting 2 numeric arguments, got %d\n"
"…offending line: '%s'", buf2, retval, line);
exit(1);
}
obj_proto[i].affected[j].location = t[0];
obj_proto[i].affected[j].modifier = t[1];
j++;
break;
case 'B':
if (j >= MAX_SOCKET_AFFECT) {
log("SYSERR: Too many B fields (%d max), %s", MAX_SOCKET_AFFECT, buf2);
exit(1);
}
if (!get_line(obj_f, line)) {
log("SYSERR: Format error in 'B' field, %s\n"
"…expecting 2 numeric constants but file ended!", buf2);
exit(1);
}

if ((retval = sscanf(line, " %d %d ", t, t + 1)) != 2) {
log("SYSERR: Format error in 'B' field, %s\n"
"…expecting 2 numeric arguments, got %d\n"
"…offending line: '%s'", buf2, retval, line);
exit(1);
}
obj_proto[i].bonus[j].location = t[0];
obj_proto[i].bonus[j].modifier = t[1];
j++;
break;
case 'T': /* DG triggers */
dg_obj_trigger(line, &obj_proto[i]);
break;
case '$':
case '#':
top_of_objt = i;
check_object(obj_proto + i);
i++;
return (line);
default:
log("SYSERR: Format error in (%c): %s", *line, buf2);
exit(1);
}
}
}


Now to be more detailed in what I added when programming sockets and socket affects, this is what I added to parse_object:

This code checks min/max sockets in the .obj file:

if (!get_line(obj_f, line)) {
log("SYSERR: Expecting fourth numeric line of %s, but file ended!", buf2);
exit(1);
}
if ((retval = sscanf(line, "%d %d", t, t + 1)) != 2) {
if(retval == 0) {
t[0] = 0;
t[1] = 0;
} else if (retval == 1)
t[1] = 0;
else {
log("SYSERR: Format error in fourth numeric line (expecting 2 args, got %d), %s", retval, buf2);
exit(1);
}
}
GET_OBJ_SOCKET_MIN(obj_proto + i) = t[0];
GET_OBJ_SOCKET_MAX(obj_proto + i) = t[1];


This code checks the sockets affect flags:

for (j= 0; j < MAX_SOCKET_AFFECT; j++) {
obj_proto[i].bonus[j].location = SOCKET_NONE;
obj_proto[i].bonus[j].modifier = 0;
}


If this finds the B it checks the socket affect line:

case 'B':
if (j >= MAX_SOCKET_AFFECT) {
log("SYSERR: Too many B fields (%d max), %s", MAX_SOCKET_AFFECT, buf2);
exit(1);
}
if (!get_line(obj_f, line)) {
log("SYSERR: Format error in 'B' field, %s\n"
"…expecting 2 numeric constants but file ended!", buf2);
exit(1);
}

if ((retval = sscanf(line, " %d %d ", t, t + 1)) != 2) {
log("SYSERR: Format error in 'B' field, %s\n"
"…expecting 2 numeric arguments, got %d\n"
"…offending line: '%s'", buf2, retval, line);
exit(1);
}
obj_proto[i].bonus[j].location = t[0];
obj_proto[i].bonus[j].modifier = t[1];
j++;
break;


Now you may ask, let me see how you have the "B" saving, here is the code in genobj.c that saves socket affects:

for (counter3 = 0; counter3 < MAX_SOCKET_AFFECT; counter3++)
if(obj->bonus[counter3].modifier)
fprintf(fp, "B\n"
"%d %d\n", obj->bonus[counter3].location, obj->bonus[counter3].modifier);
[code]

Now here is a look at an object #1

[code]
#1
wings~
a pair of wings~
A pair of wings is sitting here.~
~
9 0 0 0 0 ae 0 0 0 0 0 0 0
6 0 0 0
1 1 0 0 0
[/code]

Now clearly we can see that the fourth numeric line is missing. Which should be 0 0. Does anything have any ideas to fix this so people will not have to object wipe?
20 Nov, 2012, Davion wrote in the 2nd comment:
Votes: 0
With these types of modifications, there's a process you must go through. You cannot make modifications to both the saving and loading protocols and expect your MUD to reboot fine when you have such a ridged file format. You always want to make your modifications to your saving first, copyover/reboot your MUD, save your world, modify loading protocols, then reboot/copyover.
20 Nov, 2012, Rarva.Riendf wrote in the 3rd comment:
Votes: 0
This should always be tested in a test environment and never on your production code. So you can revert to previous situation and create for yourself a document that details everything you must do to push the change on production. If you are modifying player files I suggest you have an option to load them all and save them while the mud boot.
21 Nov, 2012, Runter wrote in the 4th comment:
Votes: 0
Davion said:
With these types of modifications, there's a process you must go through. You cannot make modifications to both the saving and loading protocols and expect your MUD to reboot fine when you have such a ridged file format. You always want to make your modifications to your saving first, copyover/reboot your MUD, save your world, modify loading protocols, then reboot/copyover.


Pretty good reason not to use a ridged format. :)
21 Nov, 2012, Liko wrote in the 5th comment:
Votes: 0
See the test was on MY(modified version of tbamud) mud, but when I tried to apply it to stock tbamud I get the crash. When I applied it to my mud, I had no crash or anything.
21 Nov, 2012, Liko wrote in the 6th comment:
Votes: 0
Rarva.Riendf said:
This should always be tested in a test environment and never on your production code. So you can revert to previous situation and create for yourself a document that details everything you must do to push the change on production. If you are modifying player files I suggest you have an option to load them all and save them while the mud boot.


It was tested. It's only having crashing problems when testing on a stock tbamud. I'm only modifying .obj files, not players.
21 Nov, 2012, arholly wrote in the 7th comment:
Votes: 0
No, but the principle is the same.
21 Nov, 2012, Rarva.Riendf wrote in the 8th comment:
Votes: 0
Liko said:
It was tested. It's only having crashing problems when testing on a stock tbamud. I'm only modifying .obj files, not players.


A bug does not always lead to a crash. The fact that it crashes on a stock TBA without you understanding why should raise a concern about the validity of the code even on your mud You could read/write wrong value and not necesserily know it till some real obvious glaring error show. All armors being set to a reasonnable value cause you read the wrong line wont crash anything, nor even raise a concern on unsuspecting players. And that was jsut an example of what could happen

Hell it could even crash later, as any modication to code lead to a different memory allocation, thus it could crash on stock mud right away, and on yours like days later. The same bug does not lead to same problems for a lot of reasons.
.
And you are saying you are modifying object but not player, I dunno about tbamud, but objects are saved on players too on some muds.
0.0/8