0

This is my first post on here. I require a bit of help for a bit of an oddball system here. Basically what I have is a registration/user signup embedded in a game of mine and I have in place a system that adheres to 128x128 pixel size avatars for users using a render target.

https://www.dropbox.com/s/5vw8i9151uz6zkn/Screenshot%202014-12-08%2021.33.11.png?dl=0

I have a system online that is supposed to recieve the image data, save it to a file, and then assign the image to a user that is logged in. However when I send over the image data, it saves to a file just fine but is not a proper png file for some reason. I have the render target saving to a proper image file on the client side using the following code

    public static void SaveToGLPng(this Microsoft.Xna.Framework.Graphics.Texture2D texture, Stream s)
    {
        byte[] imageData = new byte[4 * texture.Width * texture.Height];
        texture.GetData<byte>(imageData);
        //Since OpenGL is a special snowflake, switch around the R and B values
        for (int i = 0; i < imageData.Length; i += 4)
        {
            byte temp = imageData[i];   //store r
            imageData[i] = imageData[i+2];//swap r
            imageData[i+2] = temp;//swap b
        }

        int bp = 0;
        System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(texture.Width, texture.Height);
        System.Drawing.Imaging.BitmapData bmData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, texture.Width, texture.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat);
        IntPtr pnative = bmData.Scan0;
        System.Runtime.InteropServices.Marshal.Copy(imageData, 0, pnative, 4 * texture.Width * texture.Height);
        bitmap.UnlockBits(bmData);
        bitmap.Save(s, System.Drawing.Imaging.ImageFormat.Png);
    }
}

So that all works fine, I save the data it returns to a memory stream and pass it to a class called WebCall which implements Async WebClient Functionality

Class called for WebCall

    public void MakeCall()
    {
        using (WebClient wb = new WebClient())
        {
            UriBuilder b = new UriBuilder(url);
            wb.UploadValuesCompleted += wb_UploadValuesCompleted;
            wb.UploadValuesAsync(b.Uri, paramSet);
        }
    }

Constructor Method

    public static WebCall UploadAvatar(byte[] data, int userID)
    {
        WebCall call = new WebCall();
        call.url = URL;
        call.WriteParam("action", "upload_avatar_game");
        call.WriteParam("game", "true");
        call.WriteParam("userID", userID.ToString());
        call.WriteParam("file_data", Encoding.Default.GetString(data));
        return call;
    }

Where I am making the WebCall

            MemoryStream pngStream = new MemoryStream();
            captureTarget.SaveToGLPng(pngStream);

            var webCall = Tools.WebCall.UploadAvatar(pngStream.GetBuffer(),infoContext.UserID);
            webCall.OnCallCompleted +=webCall_OnCallCompleted;
            webCall.MakeCall();
            pngStream.Close();

And it all gets to the server just fine where it calls this method

function upload_avatar_game($params){
    $upload_dir = "../files/avatars/";

    $data = $params['file_data'];

    $dt = new DateTime();
    $dtform = $dt->format("Y-m-d-H.i.s");

    $name = $dtform . ".png";
    $fullpath = $upload_dir . $name;

    if(!isset($params['userID'])){
        echo 'false';
        die();
    }

    $user_id = $params['userID'];
    try {
        $existing_file = FileModel::get_user_avatar($user_id);

        if($existing_file){
            unlink($existing_file->getDownloadPath());
            $existing_file->setIsDeleted(true);
            $existing_file->Save();
        }

        $success = file_put_contents($fullpath,$data);
        if($success){
            $size = filesize($fullpath);
            $file = FileModel::create_file($name,$upload_dir,0,$size,$user_id);
            if($file){
                $fid = $file->getFileID();
                echo 'true';
                die();
            }
        }

    } catch(Exception $ex){
        $GLOBALS['partial'] = '../partials/error.php';
        $GLOBALS['error_msg'] = $ex->getMessage();
    }
}

Here is where the params are being passed to the method. There is testing to see if it is a legitmate request but nothing is being done to the 'file_data' entry though

function process_script(){    
    if(!isset($_GET['action']) && !isset($_POST['action']))
    {
        header('Location: ?action=login_user');
    }

    $params = isset($_GET['action']) ? $_GET : $_POST;

    //test for legimate request.

    //after test
    switch($params['action'])
    {
        case "upload_avatar_game":
            if(isset($params['game']))
            {
                upload_avatar_game($params);
            } else {
                upload_avatar($params['fileUpload']);
            }
            break;
        }
    }

It gets created and added to my DB but the data sent over is all garbled? Am I doing something wrong for transfer here?

Thanks Aaron Stewart

baldrs
  • 2,132
  • 25
  • 34
  • Please show the code which passes `$params` to the `upload_avatar_game`. Does `WebCall` sends `POST` request by default? – baldrs Dec 09 '14 at 14:56
  • How it is "garbled" then? How does `WebCall` encodes the transfer? It may need additional decoding on the server side. – baldrs Dec 09 '14 at 15:07
  • call.WriteParam("file_data", Encoding.Default.GetString(data)); This is how I am encoding it. I am unsure if I need to decode it or something? – Aaron Stewart Dec 09 '14 at 15:10
  • http://stackoverflow.com/questions/10237983/upload-to-php-server-from-c-sharp-client-application you can try conventional file upload instead of reinventing the weel – baldrs Dec 09 '14 at 15:14

2 Answers2

0

I think the answer is removing Encoding.Default.GetString and just pass bytes to the web call.

Other option might be you do not set form encoding as multipart/form-data though I'm not sure you use forms at all.

Jure Špik
  • 331
  • 2
  • 11
0

This link describes simpler approach, which utilizes the file upload in a way similar to how a web browser does it:

Upload to PHP server from c sharp client application

The point is that you generate your image, save it to a temporary file.

Then you upload it to the server, grab it from $_FILES and save it where do you need, write it to DB, etc.

And then you remove your temporary file and continue to what you intend to do next.

How to handle file uploads server-side you can find in documentation on how to upload files in php.

Community
  • 1
  • 1
baldrs
  • 2,132
  • 25
  • 34