@@ -841,8 +841,8 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name)
841841 return PyLong_FromLong (u_enum->FindEnumIndex (item.Key ));
842842#endif
843843 }
844+ }
844845 }
845- }
846846#endif
847847 if (self->ue_object ->IsA <UEnum>()) {
848848 UEnum *u_enum = (UEnum *)self->ue_object ;
@@ -852,15 +852,15 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name)
852852#else
853853 return PyLong_FromLong (u_enum->FindEnumIndex (FName (UTF8_TO_TCHAR (attr))));
854854#endif
855- }
856- }
855+ }
856+ }
857857
858858 if (function) {
859859 // swallow previous exception
860860 PyErr_Clear ();
861861 return py_ue_new_callable (function, self->ue_object );
862862 }
863- }
863+ }
864864 }
865865 return ret;
866866}
@@ -1475,7 +1475,7 @@ void unreal_engine_py_log_error() {
14751475 PyObject *zero = PyUnicode_AsUTF8String (PyObject_Str (value));
14761476 if (zero) {
14771477 msg = PyBytes_AsString (zero);
1478- }
1478+ }
14791479#else
14801480 msg = PyString_AsString (PyObject_Str (value));
14811481#endif
@@ -1521,7 +1521,7 @@ void unreal_engine_py_log_error() {
15211521 }
15221522
15231523 PyErr_Clear ();
1524- }
1524+ }
15251525
15261526// retrieve a UWorld from a generic UObject (if possible)
15271527UWorld *ue_get_uworld (ue_PyUObject *py_obj) {
@@ -1595,7 +1595,7 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer) {
15951595
15961596 if (auto casted_prop = Cast<UByteProperty>(prop)) {
15971597 int8 value = casted_prop->GetPropertyValue_InContainer (buffer);
1598- return PyLong_FromLong (value);
1598+ return PyLong_FromUnsignedLong (value);
15991599 }
16001600
16011601#if ENGINE_MINOR_VERSION >= 15
@@ -1704,9 +1704,17 @@ PyObject *ue_py_convert_property(UProperty *prop, uint8 *buffer) {
17041704
17051705 if (auto casted_prop = Cast<UArrayProperty>(prop)) {
17061706 FScriptArrayHelper_InContainer array_helper (casted_prop, buffer);
1707- PyObject *py_list = PyList_New ( 0 );
1707+
17081708 UProperty *array_prop = casted_prop->Inner ;
17091709
1710+ // check for TArray<uint8>, so we can use bytearray optimization
1711+ if (auto uint8_tarray = Cast<UByteProperty>(array_prop)) {
1712+ uint8 *buf = array_helper.GetRawPtr ();
1713+ return PyByteArray_FromStringAndSize ((char *)buf, array_helper.Num ());
1714+ }
1715+
1716+ PyObject *py_list = PyList_New (0 );
1717+
17101718 for (int i = 0 ; i < array_helper.Num (); i++) {
17111719 PyObject *item = ue_py_convert_property (array_prop, array_helper.GetRawPtr (i));
17121720 if (!item) {
@@ -1818,6 +1826,56 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer) {
18181826 return false ;
18191827 }
18201828
1829+ if (PyBytes_Check (py_obj)) {
1830+ if (auto casted_prop = Cast<UArrayProperty>(prop)) {
1831+ FScriptArrayHelper_InContainer helper (casted_prop, buffer);
1832+
1833+ if (auto item_casted_prop = Cast<UByteProperty>(casted_prop->Inner )) {
1834+
1835+ Py_ssize_t pybytes_len = PyBytes_Size (py_obj);
1836+
1837+ // fix array helper size
1838+ if (helper.Num () < pybytes_len) {
1839+ helper.AddValues (pybytes_len - helper.Num ());
1840+ }
1841+ else if (helper.Num () > pybytes_len) {
1842+ helper.RemoveValues (pybytes_len, helper.Num () - pybytes_len);
1843+ }
1844+
1845+ uint8 *buf = (uint8 *)PyBytes_AsString (py_obj);
1846+ FMemory::Memcpy (helper.GetRawPtr (), buf, pybytes_len);
1847+ return true ;
1848+ }
1849+ }
1850+
1851+ return false ;
1852+ }
1853+
1854+ if (PyByteArray_Check (py_obj)) {
1855+ if (auto casted_prop = Cast<UArrayProperty>(prop)) {
1856+ FScriptArrayHelper_InContainer helper (casted_prop, buffer);
1857+
1858+ if (auto item_casted_prop = Cast<UByteProperty>(casted_prop->Inner )) {
1859+
1860+ Py_ssize_t pybytes_len = PyByteArray_Size (py_obj);
1861+
1862+ // fix array helper size
1863+ if (helper.Num () < pybytes_len) {
1864+ helper.AddValues (pybytes_len - helper.Num ());
1865+ }
1866+ else if (helper.Num () > pybytes_len) {
1867+ helper.RemoveValues (pybytes_len, helper.Num () - pybytes_len);
1868+ }
1869+
1870+ uint8 *buf = (uint8 *)PyByteArray_AsString (py_obj);
1871+ FMemory::Memcpy (helper.GetRawPtr (), buf, pybytes_len);
1872+ return true ;
1873+ }
1874+ }
1875+
1876+ return false ;
1877+ }
1878+
18211879 if (PyList_Check (py_obj)) {
18221880 if (auto casted_prop = Cast<UArrayProperty>(prop)) {
18231881 FScriptArrayHelper_InContainer helper (casted_prop, buffer);
@@ -1845,6 +1903,33 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer) {
18451903 return false ;
18461904 }
18471905
1906+ if (PyTuple_Check (py_obj)) {
1907+ if (auto casted_prop = Cast<UArrayProperty>(prop)) {
1908+ FScriptArrayHelper_InContainer helper (casted_prop, buffer);
1909+
1910+ UProperty *array_prop = casted_prop->Inner ;
1911+ Py_ssize_t pytuple_len = PyTuple_Size (py_obj);
1912+
1913+ // fix array helper size
1914+ if (helper.Num () < pytuple_len) {
1915+ helper.AddValues (pytuple_len - helper.Num ());
1916+ }
1917+ else if (helper.Num () > pytuple_len) {
1918+ helper.RemoveValues (pytuple_len, helper.Num () - pytuple_len);
1919+ }
1920+
1921+ for (int i = 0 ; i < (int )pytuple_len; i++) {
1922+ PyObject *py_item = PyTuple_GetItem (py_obj, i);
1923+ if (!ue_py_convert_pyobject (py_item, array_prop, helper.GetRawPtr (i))) {
1924+ return false ;
1925+ }
1926+ }
1927+ return true ;
1928+ }
1929+
1930+ return false ;
1931+ }
1932+
18481933 // structs
18491934
18501935 if (ue_PyFVector *py_vec = py_ue_is_fvector (py_obj)) {
0 commit comments