I am getting started with Unreal Engine 4. I come from Libgdx and I am familiarized using WebSockets clients in my games and NodeJS with 'ws' on the server.
How ever, I can't find information about Websockets and Unreal Engine 4.
I know that given that it is programmed with C++ you can add external static libraries to the unreal project.
Can I use this c++ websocket library?
https://github.com/zaphoyd/websocketpp
Will it run on Windows, Mac and console?
I am not an expert of c++ and static libraries.
Please help, thanks!
You can follow this tutorial on TCP Sockets.
You will need to make some changes on the code, as it doesn't run on UE 4.10 (the tutorial is originally from 2014).
On the .h file define 2 timer handles:
FTimerHandle TimerHandle_Connection;
FTimerHandle TimerHandle_Socket;
On the .cpp file, inside StartTCPReceiver(...) change the line where the timer is set to:
GetWorldTimerManager().SetTimer(TimerHandle_Connection, this, &AYourClass::TCPConnectionListener, 0.01, true);
and on TCPConnectionListener(...) change the line where the timer is set to:
GetWorldTimerManager().ClearTimer(TimerHandle_Connection);//optional, only if you want to stop listening for new connections
GetWorldTimerManager().SetTimer(TimerHandle_Socket, this, &AYourClass::TCPSocketListener, 0.01, true);
(Another option would be to thread these functions instead of having them in timers)
Just in case, if you are new to UE, don't add the code directly on the IDE. Go to the Content Browser > Add New > New C++ Class. You can create a new class that inherits from Actor, and when you want to start to listen to connections, you spawn that Actor.
You can use any websocket or third party asset with unreal engine. You can simply add the headers in your Build.cs file using PrivateIncludePathModuleNames for example (there's also a public include path) and it takes an array of strings where each string is a folder essentially. If you want to add a library (lib) file you can just add it like this:
if (Target.Platform == UnrealTargetPlatform.Win32 ||
Target.Platform == UnrealTargetPlatform.Win64)
{
PublicSystemLibraries.Add("crypt32.lib");
}
You can also add full paths here. If you want to do a delayed load you can just use PublicDelayLoadedDlls.Add("name") <- I may have the syntax wrong on this one but it's easy to google it.
Related
I am developing a mobile game using Cocos2D-x engine for android platform and i want to integrate GPGS on it.
I achieved to show leaderboards, but there is a little annoying problem. When leaderboard is visible, if i go background and then come back to app, the gamescene goes to black. I think opengl context being released and doesnt restore again. In my opinion running leaderboard on same activity causes this, the game engine cant understand whats happening there. Whatever, because of this I want to run leaderboard (and also all GPGS things) on a new activity using intent.
Google likes "Providing"
In the reference documents of Google Play Game Services C++ SDK, there is a few unclear/fuzzy explanation about using SetOptionalIntentHandlerForUI method.
"Provide a function that can start a provided UI intent at any point, using startActivityForResult."
What is the mean of "Providing"? What is a provided Intent? How will I use startActivityForResult method? Unfortunately, "using" and "providing methods" are not clear expressions for coding. There is no sample about
using this method in the documents of GPGS for C++. Eventually,
Google's document is so poor and
there is no useful information on the internet. If someone from Google helps me, I will be so happy.
As i understand, I wrote the code like this. But it gives error when starting.
AppActivity.java
public void runGPGSActivity(Intent i) {
startActivityForResult(i,100);
}
AndroidPlatformConfiguration.h (From C++ gpg lib)
typedef std::function<void(jobject)> IntentHandler;
AndroidPlatformConfiguration &SetOptionalIntentHandlerForUI(
IntentHandler intent_handler);
main.cpp (JNI binding, the working code, GPGS runs on same activity )
gpg::AndroidPlatformConfiguration platform_configuration;
platform_configuration.SetActivity(activity);
StateManager::InitServices( ...
main.cpp (JNI binding, GPGS must be run on new activity )
gpg::AndroidPlatformConfiguration platform_configuration;
jclass activityClass = env->FindClass("org/cocos2dx/cpp/AppActivity");
jmethodID jIntentHandlerMethodID = env->GetMethodID(activityClass,"runGPGSActivity","(Landorid/content/Intent;)V");
jobject jIntentHandler = env->NewObject(activityClass, jIntentHandlerMethodID);
gpg::AndroidPlatformConfiguration::IntentHandler mIntentHandler; /*= [](jobject mjIntentHandler){};*/
std::function<void(jobject)> intentHandler = std::bind(mIntentHandler,jIntentHandler);
platform_configuration.SetOptionalIntentHandlerForUI(intentHandler);
platform_configuration.SetActivity(activity);
StateManager::InitServices(
There is no build error, but the application crashes when launching.
03-24 14:12:24.301: A/libc(21352): Fatal signal 6 (SIGABRT) at
0x00005368 (code=-6), thread 21352 (main)
And some links about this issue:
IntentHandler reference
StartActivityForResult reference
/// Thank you in advance. ///
...Yeah I solved the problem, but didn't use IntentHandler method.
I was using this code in my app, to show weekly leaderboard data.
gameServices->Leaderboards().ShowUIBlocking(leaderboardId,gpg::LeaderboardTimeSpan::WEEKLY);
But return value is not void, it is UIStatus (whatever it is)
I've reverted back to this code, app is not going to black screen now. This method returns void, I think I have to catch some callbacks when using ShowUIBlocking method, with that UIStatus thing.
gameServices->Leaderboards().ShowUI(leaderboardId);
But now, I can't benefit from timespan feature of leaderboards.
I am going to research how it can be used. There is no problem for now. But, documentation of SetOptionalIntentHandlerForUI must be written more explicit, for programmers who want to use it.
How can I create a Java or Javascript JSON webservice to retrieve data from a simple properties file? My intention is to uses this as a global property storage for a Jenkins instance that runs many Unit tests. The master property file also needs to be capable of being manually edited and stored in source control.
I am just wondering what method people would recommend that would be the easiest for a junior level programmer like me. I need read capability at miniumum but, and if its not too hard, write capability also. Therefore, that means it is not required to be REST.
If something like this already exists in Java or Groovy, a link to that resource would be appreciated. I am a SoapUI expert but I am unsure if a mock service could do this sort of thing.
I found something like this in Ruby but I could not get it to work as I am not a Ruby programmer at all.
There are a multitude of Java REST frameworks, but I'm most familiar with Jersey so here's a Groovy script that gives a simple read capability to a properties file.
#Grapes([
#Grab(group='org.glassfish.jersey.containers', module='jersey-container-grizzly2-http', version='2.0'),
#Grab(group='org.glassfish.jersey.core', module='jersey-server', version='2.0'),
#Grab(group='org.glassfish.jersey.media', module='jersey-media-json-jackson', version='2.0')
])
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory
import org.glassfish.jersey.jackson.JacksonFeature
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
#Path("properties")
class PropertiesResource {
#GET
#Produces("application/json")
Properties get() {
new File("test.properties").withReader { Reader reader ->
Properties p = new Properties()
p.load(reader)
return p
}
}
}
def rc = new org.glassfish.jersey.server.ResourceConfig(PropertiesResource, JacksonFeature);
GrizzlyHttpServerFactory.createHttpServer('http://localhost:8080/'.toURI(), rc).start()
System.console().readLine("Press any key to exit...")
Unfortunately, since Jersey uses the 3.1 version of the asm library, there are conflicts with Groovy's 4.0 version of asm unless you run the script using the groovy-all embeddable jar (it won't work by just calling groovy on the command-line and passing the script). I also had to supply an Apache Ivy dependency. (Hopefully the Groovy team will resolve these in the next release--the asm one in particular has caused me grief in the past.) So you can call it like this (supply the full paths to the classpath jars):
java -cp ivy-2.2.0.jar:groovy-all-2.1.6.jar groovy.lang.GroovyShell restProperties.groovy
All you have to do is create a properties file named test.properties, then copy the above script into a file named restProperties.groovy, then run via the above command line. Then you can run the following in Unix to try it out.
curl http://localhost:8080/properties
And it will return a JSON map of your properties file.
I want to create a native (c++) module for node.js which is able to send sockets to another node process, which is completely unrelated to the current process. To do so, I tought of using the ancillary library, which has a really, really easy API for this. The problem I have to solve now is how I can get the fd or the handle of a socket object of node.js.
There's a TCPWrap class in tcp_wrap.cc & tcp_wrap.h, which has a property called handle_, which holds a uv_tcp_t object from libuv, but that property is private. Also I can't #include because it's just a module of node.js an not directly in node.js itself. I don't know if it's a good idea to copy the source files to my module just to get the that class...
Have you any ides how I could do it?
I doesn't have to run on winows, tough.
Thanks!
I finally found a way to do it. You can find the node module here:
https://github.com/VanCoding/node-ancillary
I've just taken the headers "tcp_wrap.h","stream_wrap.h" and "handle_wrap.h" and then included "tcp_wrap.h".
I could then get the object the following way:
TCPWrap* wrap = static_cast<TCPWrap*>(args[0]->ToObject()->GetPointerFromInternalField(0));
StreamWrap* s = (StreamWrap*)wrap;
The following code then gives access to the file descriptor
s->GetStream()->fd
Firstly please let me explain what I am trying to do:
I am using Qt to build an app mainly based on webkit. This app fetches content from internet and present it to user by traditional web way.
My app has to communicate many serial port devices, such as printer, IC card reader.
These serial port devices have different models, so that they have different communication protocol.
I want separate my app with the serial port devices communcating part, so that I can only update the communcation part without updating all the app.
Do I need to write a Qt plugin/webkit plugin, or some other way to do this? Any suggestions are welcome!
Thanks
AFAIK Qt already provides a plugin mechanism.
Check the QLibrary class out and the examples there.
For the serial port part qextserialport
Build your communication part in a dll/dynamic library by using TARGET = lib and CONFIG += dll in another qmake file.
I would suggest one of the PluginManager style plugin methods with C++.
I'm writing this from 2+ year old memory so it's meant only as a loose guide, not a definitive answer.
I have included a link to a site I used to get started on a project like you describe a few years ago. It worked well with the 40+ plugins we had available.
A search for [DLL plugin C++ class] should find several of the sites for you if you don't like the one I linked.
You will have to correct for your environment/compiler/OS etc.
In essence, assume you want the ability to Open, Read, Write and Close the serial ports in your plugins.
Create a pure virtual base class (Acts as something declared as an interface in Java):
/* This is the basic plugin header file that every plugin DLL has to include
Use your compilers pragmas/keywords to export the entire class from the DLL
In Microsoft land the keywords are _declspec( dllexport ) to export the class
from the base DLL and __declspec( dllimport ) to import the class into other
code. I'm using the MS keywords here because I don't remember how this is done
in other compilers. :)
*/
#if BUILDING_BASE_PLUGIN
/* You're compiling the DLL that exports the Plugin Base
#define BASE_DLL_EXPORT declspec( dllexport )
#else
/* You're compiling code that uses the plugin base
#define BASE_DLL_EXPORT declspec( dllimport )
#endif
class DLL_EXPORT SerialPortPluginBase
{
public:
enum SerialPortPluginError{ SUCCESS = 0, ERROR_1, ERROR_2, ERROR_ETC };
virtual SerialPortPluginError Open( /*Parameters*/ ) = 0;
virtual SerialPortPluginError Read( /*Parameters*/ ) = 0;
virtual SerialPortPluginError Write( /*Parameters*/ ) = 0;
virtual SerialPortPluginError Close( /*Parameters*/ ) = 0;
static std::string pluginName = "SerialPortPluginBase";
static int version;
};
In each plugin, implement the interface based on the above class as well as a method to register/unregister the DLL with a plugin manager (see the link below).
Each plugin should go in a separate DLL/SO.
See this site for a complete example.
Hope this helps. :)
What you want is to create a Qt Plugin for your application:
http://doc.qt.io/archives/qt-4.7/plugins-howto.html
You'll be able to extend your main application through a plugin. The only thing you'll need to add to your application is the process of load plugins and add some events to call plugins methods.
I'm trying to use QHttp for an update app. But there is a problem for me which I can't solve.
I try to download a file (works perfectly) but if there is no connection to the internet, the file is created but has 0 bytes. My old file is then overwritten with the empty file, which is not so good for the application trying to use the file. What I need is to check if the computer is connected to the internet.
Note: proxy may set. I used this example from Qt's homepage.
You should switch to the QNetworkAccessManager as Mike Suggested, here is an example of a slot on the finished() signal:
void ApplicationUpdate::replyFinishedhttpGetChangeLog(QNetworkReply* myReply) {
if (myReply->error() != QNetworkReply::NoError)
{
QByteArray returnedData = myReply->readAll();
if (returnedData.size() > 0) {
if( m_fileChangeLog->exists() )
{
m_fileChangeLog->close();
m_fileChangeLog->remove();
}
m_fileChangeLog->open(QIODevice::ReadWrite);
QDataStream out( m_fileChangeLog );
out.writeRawData(returnedData.data(), returnedData.size());
m_fileChangeLog->flush();
m_fileChangeLog->close();
}
}
}
Firstly, you should probably now be using QNetworkAccessManager rather than QHttp.
Using either of them, you should do a dummy query to a site you pretty much always know will be up (e.g. http://www.google.com/) and use that as a test to see if you have an internet connection.
A better way of doing this would be instead to use QNetworkAccessManager to read into a QByteArray and then check it isn't empty before writing to your file.
Whenever you write a file that might already exist, you should create a QTemporaryFile first, then, after successful download, rename it to the final name.
i ran into the same problem, after a bit of poking around, I've isolated the problem down to the project configuration file (.pro), in the broken configuration I was linking the networking library explicitly with the statement : "LIBS += -lQtNetwork". In the working configuration, I used the more formal (and qt compilant) approach of delcaring what Qt components are included in the project, like so: "QT = core gui network xml", adjust accordingly for your sitiation, the netowkring slots did not work on windows when explicitly linked but did work on linux. Using the qt compilant approach works on both platforms.