ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/friend.C
Revision: 1.11
Committed: Tue Apr 24 12:32:14 2007 UTC (17 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.10: +10 -0 lines
Log Message:
server crashed this morning because a freed golem tried to follow
his owner, triggering the assertion failure.

the golem had no owner, but the owner still had him in his range slots.

I refactored a bit of the code and rearranged it to hopefully increase
chances of this not occuring again.

File Contents

# User Rev Content
1 elmex 1.1 /*
2 pippijn 1.10 * CrossFire, A Multiplayer game for X-windows
3     *
4     * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5     * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
6     * Copyright (C) 1992 Frank Tore Johansen
7     *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21     *
22     * The authors can be reached via e-mail at <crossfire@schmorp.de>
23     */
24 elmex 1.1
25     #include <global.h>
26    
27     /*
28     * Add a new friendly object to the linked list of friendly objects.
29     * No checking to see if the object is already in the linked list is done.
30     */
31 root 1.5 void
32     add_friendly_object (object *op)
33     {
34 root 1.9 op->flag [FLAG_FRIENDLY] = 1;
35    
36 root 1.5 objectlink *ol;
37 elmex 1.1
38 root 1.5 /* Add some error checking. This shouldn't happen, but the friendly
39     * object list usually isn't very long, and remove_friendly_object
40     * won't remove it either. Plus, it is easier to put a breakpoint in
41     * the debugger here and see where the problem is happening.
42     */
43 root 1.9 for (ol = first_friendly_object; ol; ol = ol->next)
44 root 1.5 {
45     if (ol->ob == op)
46     {
47     LOG (llevError, "add_friendly_object: Trying to add object already on list (%s)\n", &op->name);
48     return;
49 root 1.2 }
50 elmex 1.1 }
51    
52 root 1.5 ol = first_friendly_object;
53     first_friendly_object = get_objectlink ();
54     first_friendly_object->ob = op;
55     first_friendly_object->next = ol;
56 elmex 1.1 }
57    
58     /*
59     * Removes the specified object from the linked list of friendly objects.
60     */
61 root 1.5 void
62     remove_friendly_object (object *op)
63     {
64     objectlink *obj;
65 elmex 1.1
66 root 1.5 CLEAR_FLAG (op, FLAG_FRIENDLY);
67 elmex 1.1
68 root 1.11 if (op->type == GOLEM
69     && op->owner
70     && op->owner->contr
71     && op->owner->contr->ranges[range_golem] == op)
72     {
73     op->owner->contr->ranges[range_golem] = 0;
74     op->owner->contr->shoottype = range_none;
75     }
76    
77 root 1.5 if (!first_friendly_object)
78     {
79     LOG (llevError, "remove_friendly_object called with empty friendly list, remove ob=%s\n", &op->name);
80     return;
81     }
82 root 1.9
83 root 1.5 /* if the first object happens to be the one, processing is pretty
84     * easy.
85     */
86     if (first_friendly_object->ob == op)
87     {
88     obj = first_friendly_object;
89     first_friendly_object = obj->next;
90 root 1.7 delete obj;
91 elmex 1.1 }
92 root 1.5 else
93     {
94     objectlink *prev = first_friendly_object;
95    
96 root 1.9 for (obj = first_friendly_object->next; obj; obj = obj->next)
97 root 1.5 {
98     if (obj->ob == op)
99     break;
100 root 1.11
101 root 1.5 prev = obj;
102 root 1.2 }
103 root 1.7
104 root 1.5 if (obj)
105     {
106     prev->next = obj->next;
107 root 1.7 delete obj;
108 root 1.2 }
109 elmex 1.1 }
110     }
111    
112     /*
113 root 1.9 * Dumps all friendly objects.
114 elmex 1.1 */
115 root 1.5 void
116     dump_friendly_objects (void)
117     {
118     objectlink *ol;
119 elmex 1.1
120 root 1.9 for (ol = first_friendly_object; ol; ol = ol->next)
121 root 1.5 LOG (llevError, "%s (%d)\n", &ol->ob->name, ol->ob->count);
122 elmex 1.1 }
123    
124     /* New function, MSW 2000-1-14
125     * It traverses the friendly list removing objects that should not be here
126     * (ie, do not have friendly flag set, freed, etc)
127     */
128 root 1.5 void
129     clean_friendly_list (void)
130     {
131     objectlink *obj, *prev = NULL, *next;
132     int count = 0;
133    
134 root 1.7 for (obj = first_friendly_object; obj; obj = next)
135 root 1.5 {
136     next = obj->next;
137 root 1.7 if (QUERY_FLAG (obj->ob, FLAG_FREED) || !QUERY_FLAG (obj->ob, FLAG_FRIENDLY))
138 root 1.5 {
139     if (prev)
140 root 1.7 prev->next = obj->next;
141 root 1.5 else
142 root 1.7 first_friendly_object = obj->next;
143    
144 root 1.5 count++;
145 root 1.7 delete obj;
146 root 1.2 }
147 root 1.5 else
148 root 1.7 /* If we removed the object, then prev is still valid. */
149 root 1.5 prev = obj;
150 elmex 1.1 }
151 root 1.7
152 root 1.5 if (count)
153     LOG (llevDebug, "clean_friendly_list: Removed %d bogus links\n", count);
154 elmex 1.1 }
155    
156     /* Checks if the given object is already in the friendly list or not
157     * Lauwenmark - 31/07/05
158     */
159 root 1.5 int
160     is_friendly (const object *op)
161 elmex 1.1 {
162 root 1.5 objectlink *ol;
163 elmex 1.1
164 root 1.9 for (ol = first_friendly_object; ol; ol = ol->next)
165 root 1.5 if (ol->ob == op)
166     return 1;
167 elmex 1.1
168 root 1.5 return 0;
169 elmex 1.1 }
170 root 1.9