Atrinik Server 2.5
plugins/plugin_python/atrinik_party.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00030 #include <plugin_python.h>
00031 
00034 /* @cparser
00035  * @page plugin_python_party_fields Python party fields
00036  * <h2>Python party fields</h2>
00037  * List of the party fields and their meaning. */
00038 static fields_struct fields[] =
00039 {
00040     {"name", FIELDTYPE_SHSTR, offsetof(party_struct, name), FIELDFLAG_READONLY, 0},
00041     {"leader", FIELDTYPE_SHSTR, offsetof(party_struct, leader), 0, 0},
00042     {"password", FIELDTYPE_CARY, offsetof(party_struct, passwd), FIELDFLAG_READONLY, 0}
00043 };
00044 /* @endcparser */
00045 
00057 static PyObject *Atrinik_Party_AddMember(Atrinik_Party *party, PyObject *args)
00058 {
00059     Atrinik_Object *ob;
00060 
00061     if (!PyArg_ParseTuple(args, "O!", &Atrinik_ObjectType, &ob))
00062     {
00063         return NULL;
00064     }
00065 
00066     OBJEXISTCHECK(ob);
00067 
00068     if (ob->obj->type != PLAYER || !CONTR(ob->obj))
00069     {
00070         PyErr_SetString(PyExc_ValueError, "party.AddMember(): 'player' must be a player object.");
00071         return NULL;
00072     }
00073     else if (CONTR(ob->obj)->party)
00074     {
00075         if (CONTR(ob->obj)->party == party->party)
00076         {
00077             RAISE("party.AddMember(): The specified player object is already in the specified party.");
00078         }
00079         else
00080         {
00081             RAISE("party.AddMember(): The specified player object is already in another party.");
00082         }
00083     }
00084 
00085     hooks->add_party_member(party->party, ob->obj);
00086 
00087     Py_INCREF(Py_None);
00088     return Py_None;
00089 }
00090 
00097 static PyObject *Atrinik_Party_RemoveMember(Atrinik_Party *party, PyObject *args)
00098 {
00099     Atrinik_Object *ob;
00100 
00101     if (!PyArg_ParseTuple(args, "O!", &Atrinik_ObjectType, &ob))
00102     {
00103         return NULL;
00104     }
00105 
00106     OBJEXISTCHECK(ob);
00107 
00108     if (ob->obj->type != PLAYER || !CONTR(ob->obj))
00109     {
00110         PyErr_SetString(PyExc_ValueError, "party.RemoveMember(): 'player' must be a player object.");
00111         return NULL;
00112     }
00113     else if (!CONTR(ob->obj)->party)
00114     {
00115         RAISE("party.RemoveMember(): The specified player is not in a party.");
00116     }
00117 
00118     hooks->remove_party_member(party->party, ob->obj);
00119 
00120     Py_INCREF(Py_None);
00121     return Py_None;
00122 }
00123 
00128 static PyObject *Atrinik_Party_GetMembers(Atrinik_Party *party, PyObject *args)
00129 {
00130     PyObject *list = PyList_New(0);
00131     objectlink *ol;
00132 
00133     (void) args;
00134 
00135     for (ol = party->party->members; ol; ol = ol->next)
00136     {
00137         PyList_Append(list, wrap_object(ol->objlink.ob));
00138     }
00139 
00140     return list;
00141 }
00142 
00149 static PyObject *Atrinik_Party_SendMessage(Atrinik_Party *party, PyObject *args)
00150 {
00151     Atrinik_Object *ob = NULL;
00152     int flags;
00153     const char *msg;
00154 
00155     if (!PyArg_ParseTuple(args, "si|O!", &msg, &flags, &Atrinik_ObjectType, &ob))
00156     {
00157         return NULL;
00158     }
00159 
00160     if (ob)
00161     {
00162         OBJEXISTCHECK(ob);
00163     }
00164 
00165     hooks->send_party_message(party->party, msg, flags, ob ? ob->obj : NULL);
00166 
00167     Py_INCREF(Py_None);
00168     return Py_None;
00169 }
00170 
00174 static PyMethodDef PartyMethods[] =
00175 {
00176     {"AddMember", (PyCFunction) Atrinik_Party_AddMember, METH_VARARGS, 0},
00177     {"RemoveMember", (PyCFunction) Atrinik_Party_RemoveMember, METH_VARARGS, 0},
00178     {"GetMembers", (PyCFunction) Atrinik_Party_GetMembers, METH_NOARGS, 0},
00179     {"SendMessage", (PyCFunction) Atrinik_Party_SendMessage, METH_VARARGS, 0},
00180     {NULL, NULL, 0, 0}
00181 };
00182 
00188 static PyObject *Party_GetAttribute(Atrinik_Party *party, void *context)
00189 {
00190     return generic_field_getter((fields_struct *) context, party->party);
00191 }
00192 
00199 static int Party_SetAttribute(Atrinik_Party *party, PyObject *value, void *context)
00200 {
00201     if (generic_field_setter((fields_struct *) context, party->party, value) == -1)
00202     {
00203         return -1;
00204     }
00205 
00206     return 0;
00207 }
00208 
00215 static PyObject *Atrinik_Party_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
00216 {
00217     Atrinik_Party *self;
00218 
00219     (void) args;
00220     (void) kwds;
00221 
00222     self = (Atrinik_Party *) type->tp_alloc(type, 0);
00223 
00224     if (self)
00225     {
00226         self->party = NULL;
00227     }
00228 
00229     return (PyObject *) self;
00230 }
00231 
00235 static void Atrinik_Party_dealloc(Atrinik_Party *self)
00236 {
00237     self->party = NULL;
00238 #ifndef IS_PY_LEGACY
00239     Py_TYPE(self)->tp_free((PyObject *) self);
00240 #else
00241     self->ob_type->tp_free((PyObject *) self);
00242 #endif
00243 }
00244 
00249 static PyObject *Atrinik_Party_str(Atrinik_Party *self)
00250 {
00251     return Py_BuildValue("s", self->party->name);
00252 }
00253 
00254 static int Atrinik_Party_InternalCompare(Atrinik_Party *left, Atrinik_Party *right)
00255 {
00256     return (left->party < right->party ? -1 : (left->party == right->party ? 0 : 1));
00257 }
00258 
00259 static PyObject *Atrinik_Party_RichCompare(Atrinik_Party *left, Atrinik_Party *right, int op)
00260 {
00261     if (!left || !right || !PyObject_TypeCheck((PyObject *) left, &Atrinik_PartyType) || !PyObject_TypeCheck((PyObject *) right, &Atrinik_PartyType))
00262     {
00263         Py_INCREF(Py_NotImplemented);
00264         return Py_NotImplemented;
00265     }
00266 
00267     return generic_rich_compare(op, Atrinik_Party_InternalCompare(left, right));
00268 }
00269 
00271 static PyGetSetDef getseters[NUM_FIELDS + 1];
00272 
00274 PyTypeObject Atrinik_PartyType =
00275 {
00276 #ifdef IS_PY3K
00277     PyVarObject_HEAD_INIT(NULL, 0)
00278 #else
00279     PyObject_HEAD_INIT(NULL)
00280     0,
00281 #endif
00282     "Atrinik.Party",
00283     sizeof(Atrinik_Party),
00284     0,
00285     (destructor) Atrinik_Party_dealloc,
00286     NULL, NULL, NULL,
00287 #ifdef IS_PY3K
00288     NULL,
00289 #else
00290     (cmpfunc) Atrinik_Party_InternalCompare,
00291 #endif
00292     0, 0, 0, 0, 0, 0,
00293     (reprfunc) Atrinik_Party_str,
00294     0, 0, 0,
00295     Py_TPFLAGS_DEFAULT,
00296     "Atrinik parties",
00297     NULL, NULL,
00298     (richcmpfunc) Atrinik_Party_RichCompare,
00299     0, 0, 0,
00300     PartyMethods,
00301     0,
00302     getseters,
00303     0, 0, 0, 0, 0, 0, 0,
00304     Atrinik_Party_new,
00305     0, 0, 0, 0, 0, 0, 0, 0
00306 #ifndef IS_PY_LEGACY
00307     , 0
00308 #endif
00309 };
00310 
00315 int Atrinik_Party_init(PyObject *module)
00316 {
00317     size_t i;
00318 
00319     /* Field getters */
00320     for (i = 0; i < NUM_FIELDS; i++)
00321     {
00322         PyGetSetDef *def = &getseters[i];
00323 
00324         def->name = fields[i].name;
00325         def->get = (getter) Party_GetAttribute;
00326         def->set = (setter) Party_SetAttribute;
00327         def->doc = NULL;
00328         def->closure = (void *) &fields[i];
00329     }
00330 
00331     getseters[i].name = NULL;
00332 
00333     Atrinik_PartyType.tp_new = PyType_GenericNew;
00334 
00335     if (PyType_Ready(&Atrinik_PartyType) < 0)
00336     {
00337         return 0;
00338     }
00339 
00340     Py_INCREF(&Atrinik_PartyType);
00341     PyModule_AddObject(module, "Party", (PyObject *) &Atrinik_PartyType);
00342 
00343     return 1;
00344 }
00345 
00350 PyObject *wrap_party(party_struct *what)
00351 {
00352     Atrinik_Party *wrapper;
00353 
00354     /* Return None if no party was to be wrapped. */
00355     if (!what)
00356     {
00357         Py_INCREF(Py_None);
00358         return Py_None;
00359     }
00360 
00361     wrapper = PyObject_NEW(Atrinik_Party, &Atrinik_PartyType);
00362 
00363     if (wrapper)
00364     {
00365         wrapper->party = what;
00366     }
00367 
00368     return (PyObject *) wrapper;
00369 }