diff --git a/include/XPMPMultiplayer.h b/include/XPMPMultiplayer.h index 4c2a95286..4dabe6c5b 100644 --- a/include/XPMPMultiplayer.h +++ b/include/XPMPMultiplayer.h @@ -379,6 +379,14 @@ void XPMPGetModelInfo(int inIndex, const char **outModelName, const char **outIc XPMPPlaneData_f inDataFunc, void * inRefcon); + XPMPPlaneID XPMPCreatePlaneWithModelName( + const char * inModelName, + const char * inICAOCode, + const char * inAirline, + const char * inLivery, + XPMPPlaneData_f inDataFunc, + void * inRefcon); + /* * XPMPDestroyPlane * diff --git a/src/XPMPMultiplayer.cpp b/src/XPMPMultiplayer.cpp index 98a52e61c..948499831 100644 --- a/src/XPMPMultiplayer.cpp +++ b/src/XPMPMultiplayer.cpp @@ -27,6 +27,7 @@ #include "XPMPMultiplayerCSL.h" #include +#include #include #include #include @@ -345,7 +346,50 @@ XPMPPlaneID XPMPCreatePlane( iter->first.first(plane, xpmp_PlaneNotification_Created, iter->first.second); } return plane; -} +} + +bool CompareCaseInsensitive(string strFirst, string strSecond) +{ + // Convert both strings to upper case by transfrom() before compare. + transform(strFirst.begin(), strFirst.end(), strFirst.begin(), static_cast(std::toupper)); + transform(strSecond.begin(), strSecond.end(), strSecond.begin(), static_cast(std::toupper)); + return strFirst == strSecond; +} + +XPMPPlaneID XPMPCreatePlaneWithModelName(const char *inModelName, const char *inICAOCode, const char *inAirline, const char *inLivery, XPMPPlaneData_f inDataFunc, void *inRefcon) +{ + XPMPPlanePtr plane = new XPMPPlane_t; + plane->icao = inICAOCode; + plane->livery = inLivery; + plane->airline = inAirline; + plane->dataFunc = inDataFunc; + plane->ref = inRefcon; + + // Find the model + for (auto &package : gPackages) + { + auto cslPlane = std::find_if(package.planes.begin(), package.planes.end(), [inModelName](CSLPlane_t p) { return CompareCaseInsensitive(p.modelName, inModelName); }); + if (cslPlane != package.planes.end()) + { + plane->model = &(*cslPlane); + } + } + if (!plane->model) return nullptr; + + plane->pos.size = sizeof(plane->pos); + plane->surface.size = sizeof(plane->surface); + plane->radar.size = sizeof(plane->radar); + plane->posAge = plane->radarAge = plane->surfaceAge = -1; + + gPlanes.push_back(plane); + + for (XPMPPlaneNotifierVector::iterator iter = gObservers.begin(); iter != + gObservers.end(); ++iter) + { + iter->first.first(plane, xpmp_PlaneNotification_Created, iter->first.second); + } + return plane; +} void XPMPDestroyPlane(XPMPPlaneID inID) { diff --git a/src/XPMPMultiplayerVars.h b/src/XPMPMultiplayerVars.h index 839573b43..5b9ad2b70 100644 --- a/src/XPMPMultiplayerVars.h +++ b/src/XPMPMultiplayerVars.h @@ -154,12 +154,12 @@ struct XPMPPlane_t { string icao; string airline; string livery; - CSLPlane_t * model; // May be null if no good match + CSLPlane_t * model = nullptr; // May be null if no good match bool good_livery; // is our paint correctly matched? // This callback is used to pull data from the client for posiitons, etc. XPMPPlaneData_f dataFunc; - void * ref; + void * ref = nullptr; // This is last known data we got for the plane, with timestamps. int posAge;