[PAID] OpenVPN: Connect with VPN server using .ovpn files ($15 or INR 1001)

Do you accept that @Shreyaa is in more trouble than me?

I didn't make a single penny from it but....ykwim.

It very much. As I'm profesional modder I have more knowledge than your current knowledge.

Extension was not taken down I have written a message to mods.

So what you gonna break rules. Community rules are simple, extension decompile and sale is banned.

You are in trouble.

Both are simple. Work on same principle. The library owner needs credit. I have talked with him. People just miss use his project and published app blah blah all saying made vpn app. He was depressed.

Aix works differently. Code is changed in some classes. As it aar library there is no such support for it

He said right!. money is everything he does what he can do.

But are you gonna eat money?? Really what you had in breakfast? Some notes? Ah really

Idk. This is so bad. I thought you where old user I have some respect for you. But ...

What you think. Google launch android studio and have some classes. Which we use right? All extension belong to Google then?

Thing is my things belong to me only.

It needed to work on lower api. :grin:

He not know what the use of it

If you know can you classify which api it support?

As I know

Then it is a "very" unethical way of presenting your argument.


You missed the quoted words of the original author:


It's not about money sunny, it is never, it is about respecting Open Source Ethics and setting right example. I being myself a open source contributor, would not like anyone doing this.
This also applies to any other extension, not only yours.


Also you missed to reply to...

3 Likes

I agree. You had published your extension more than 2 years ago before I could figure out things.

No, I am not gonna break the rules. I publish similar extension since your one was made unavailable by you.

I am no stupid to miss such an opportunity where every single rupee means so much to me.
Whenever an extension developer goes offline, alternative to his extensions do emerge.

@Kumaraswamy would like to answer it. (What library owner really wants)

No, I would need to get admission in a govt B.Tech college. Counselling will start in June after JEE Advance results.

So you kept your extension paid for exactly which reason? Everyone wants to earn. Someone fame someone money.

Yes, your extension is yours and my extension is mine.
How can you even think I am a decompiler?


pie - no pie

Yes it my knowledge to load AAR.

Do you ever got a way to work with it ? Ah? No you don't

Your post already answered the questions.

Knowledge belongs to me.

What belongs to you?

So what my work Exist. I exist the one who had knowledge.

I need sorry from your side.

Hopefully you will got college, also you having very

Much much valueable things.

Btw, me too 600+ neet ug MBBS college confirmed this year.

I just login today my exam was yesterday

I said I'm professional modder. Just glimpse of complied apk it enough for me to show all things.

2 Likes

Do you agree it is not the first Open VPN extension?
Do you know how many copies of her extension have been sold?

I didn't know dex loading is also illegal. If it is really is then I would like to take down extension before I face legal consequences.


These aidl files:

Now I guess it also comes under GPLv2. :pensive:

I have already said that I overlooked license and missed some important lines.
Once I came to know paid license thing (our last conversations here which was deleted), I honestly thought of negotiating about license price once I earned some money from the extension, but I never earned enough.

It is legally. If you don't dynamically load dex like downloading from somewhere. Google allow it when it comes within apk.

Same thing Facebook also use SDK as Dex file

What you gonna do ah right?

I will take. Rules are for every one. You not gonna escape from community.

1 Like

What this thing has to do with aar?
Btw, there has been multiple R.txt to R.java convertors (One by Xoma and other by Oseamiya didi). I wrote one myself to convert strings.xml to R.string.

Can't two extension developers publish same extension?
Just go and check Taifun's extension directory.

For copying your extension idea? No.
Or copying your extension's code, which I never did? Never.

@Kumaraswamy I am sorry for whatever rude things I have said you.
But please at least enlighten her.
I am dying laughing here. :joy:

Why not to check owner library. Whether it was jar or aar.

You know what aar means? Why you acting innocent?

Code also same ?

Library have special class. Which load thing. Else no extension can work. Show that code.

@Shreyaa even the cost is same ($15)...

I am not @vknow360 I do not eat money.

It belongs to me. I am not here for money.

I am here for my right

1 Like

Yes. No.


I'm still confused, you say you are

and once you say you are using AIDL APIs... That explicitly requires Open VPN app to be installed (and it dosent require Native libraries)


No, that is also merely a redistribution of code in a different format. Repacking the code as a different file or encoding format is not an excuse at all. Even I can, for instance, convert whole library into a Base64 and decode and load it dynamically at the runtime.

Infact, your extension too violates the licensing, but there wasant a lot of awareness back then.

2 Likes

You say you are dex loading classes?
Then why do you need aar? For what purposes?

Some part of code can be same if both are using Dex Loader, but not complete code.
Neither complete features can be same.

I do not have any such code.

package com.sunny.openvpn;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.text.TextUtils;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.runtime.ActivityResultListener;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
import com.google.appinventor.components.runtime.EventDispatcher;
import com.google.appinventor.components.runtime.Form;
import com.google.appinventor.components.runtime.OnDestroyListener;
import com.google.appinventor.components.runtime.util.AsynchUtil;
import com.google.appinventor.components.runtime.util.OnInitializeListener;
import com.google.appinventor.components.runtime.util.YailList;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;

import static android.app.Activity.RESULT_OK;
import static android.content.Context.MODE_PRIVATE;

public class OpenVPN extends AndroidNonvisibleComponent implements DexCallbacks,OnInitializeListener,ActivityResultListener, OnDestroyListener {
  private final int reqCode;
  public String status = "";
  private boolean isBinded = false;
  protected Object mService = null;

  public OpenVPN(ComponentContainer container) {
    super(container.$form());
    reqCode = form.registerForActivityResult(this);
    form.registerForOnInitialize(this);
    form.registerForOnDestroy(this);
  }

  @SimpleFunction(description = "Returns whether VPN Service has been already prepared or not. If returns false then you'll have to ask Service Permission first.")
  public boolean IsVpnPrepared(){
    if (!isBinded){
      return false;
    }
    return DexUtils.prepare(form,mService) == null;
  }


  @SimpleFunction(description = "Return VPN connection state")
  public String VpnState(){
    if (status.isEmpty()) {
      return Preferences.getDefaultSharedPreferences(form).getString("vpn_service_last_status", "NOPROCESS");
    }
    return status;
  }
  @SimpleFunction(description = "Start VPN service with provided configFile and other credentials")
  public void StartVPN(String title,String configFile,String country,String username,String password){
    if ("CONNECTED".equals(VpnState()) || "USERPAUSE".equals(VpnState())) {
      return;
    }
    try {
      InputStream conf = configFile.startsWith("/") ? new FileInputStream(configFile) : form.getAssets().open(configFile);
      InputStreamReader isr = new InputStreamReader(conf);
      BufferedReader bufferedReader = new BufferedReader(isr);
      StringBuilder stringBuilder = new StringBuilder();
      String line;
      while ((line = bufferedReader.readLine()) != null) {
        stringBuilder.append(line).append("\n");
      }
      bufferedReader.close();

      DexUtils.startVpn(form, mService,title, stringBuilder.toString(), country, username, password);
    } catch (Exception e) {
      e.printStackTrace();
      ErrorOccurred(e.getMessage());
    }
  }

  @Override
  public void resultReturned(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
      VpnPermissionGranted();
    } else {
      VpnPermissionDenied();
    }
  }

  private final ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className,
                                   IBinder service) {
      isBinded = true;
      mService = DexUtils.getService(service);
    }

    public void onServiceDisconnected(ComponentName className) {
      mService = null;
      isBinded = false;
    }
  };


  @Override
  public void onDestroy() {
    if(isBinded){
      form.unbindService(mConnection);
    }
  }

  @Override
  public void onInitialize() {
    DexUtils.downloadAndLoad(this);
  }

  @SimpleFunction(description = "Ask for service permissions required to start VPN")
  public void AskServicePermission(){
    Intent intent = DexUtils.prepare(form,mService);
    if (intent != null){
      form.startActivityForResult(intent,reqCode);
    }
  }

  @SimpleEvent(description = "Event raised when error occurs. It is not guaranteed that all errors will be reported via this event. However, all of them will be reported to logs. ")
  public void ErrorOccurred(String errorMsg){
    EventDispatcher.dispatchEvent(this,"ErrorOccurred",errorMsg);
  }

  @SimpleEvent(description = "Event raised when VPN connection state changes")
  public void StateChanged(String state){
    EventDispatcher.dispatchEvent(this,"StateChanged",state);
  }
  @SimpleFunction(description = "Returns Allowed Apps list")
  public YailList GetAllowedAppsList(){
    return YailList.makeList(getList());
  }

  @SimpleEvent(description = "Event raised after collecting all logs")
  public void GotLogs(String logs){
    EventDispatcher.dispatchEvent(this,"GotLogs",logs);
  }
  @SimpleEvent(description = "Event raised when VPN permission is granted. Vpn can be started only in this case.")
  public void VpnPermissionGranted(){
    EventDispatcher.dispatchEvent(this,"VpnPermissionGranted");
  }

  @SimpleEvent(description = "Event raised when VPN permission is denied")
  public void VpnPermissionDenied(){
    EventDispatcher.dispatchEvent(this,"VpnPermissionDenied");
  }

  public static String[] getList(){
    SharedPreferences preferences = Form.getActiveForm().getSharedPreferences("VPN_prefs",MODE_PRIVATE);
    return preferences.getString("mAllowedApps","").split(",");
  }

  @SimpleFunction(description = "Adds specified app to Allowed Apps List. Apps in this list bypass VPN.")
  public void AddAllowedApp(String pkgName){
    SharedPreferences.Editor preferences = form.getSharedPreferences("VPN_prefs",MODE_PRIVATE).edit();
    YailList list = GetAllowedAppsList();
    list.add(pkgName);
    preferences.putString("mAllowedApps", TextUtils.join(",",list.toStringArray()));
  }

  @SimpleFunction(description = "Removes specified app from Allowed Apps list")
  public void RemoveAllowedApp(String pkgName){
    SharedPreferences.Editor preferences = form.getSharedPreferences("VPN_prefs",MODE_PRIVATE).edit();
    YailList list = GetAllowedAppsList();
    list.remove(pkgName);
    preferences.putString("mAllowedApps",TextUtils.join(",",list.toStringArray()));
  }

  @SimpleFunction(description = "Stop VPN Service ")
  public void StopVPN(){
    if (mService != null) {
      try {
        DexUtils.stopOpenVpn(form,mService);
      } catch (Exception e) {
        ErrorOccurred(e.getMessage());
      }
    }
  }


  @Override
  public void classesLoaded() {
    if (!isBinded) {
      Intent service = new Intent(DexUtils.getServiceClass().getClass().getName());
      service.setPackage("de.blinkt.openvpn");
      form.bindService(service, mConnection, Context.BIND_AUTO_CREATE);
    }
  }

  @Override
  public void newStatus(String uuid, String state, String message, String level) {
    StateChanged(state);
    Preferences.getDefaultSharedPreferences(form).edit().putString("vpn_service_last_status",state).commit();
  }

  @SimpleFunction(description = "Clear logs of current session")
  public void ClearLogs(){
    DexUtils.getVpnStatus().clearLog();
  }

  @SimpleFunction(description = "Read logs from the log file of current session")
  public void GetLogs(){
    AsynchUtil.runAsynchronously(new Runnable() {
      @Override
      public void run() {
        final StringBuilder str = new StringBuilder();
        for (String entry : DexUtils.getLogList()) {
          str.append(entry);
        }
        form.runOnUiThread(new Runnable() {
          @Override
          public void run() {
            GotLogs(str.toString());
          }
        });
      }
    });
  }
}

Then why you initially talked about injection of native libraries, why was it even needed when what u do is just dexloading / calling from intent? Why need assets? Also, why deleted your old replies stating the repo you took the code from?

All everyone here sees, is a bunch of contradicting statements, nothing else.

@Kumaraswamy how you gonna know the number of copies.

Extension code don't have anything it is very simple.

Show the library which load dex

lets settle down first, in order to not flood community

Class references.


Violates? Are you serious?
She has made quite a lot of money from it and still not a single question was asked.
@Know_About_IT wrote epic work there.

And same people are showing biasedness here.
And here I am with 0 sales and answering hell lot of questions.
What kind of partiality is this?

Show the loader class.

Library have that class

Library is also modified otherwise it not gonna work

He thought, he can fool everyone I like I did in my original post

No, I won't.
Instead I would take down extension.

Your extension will go down as well.
And now you be ready to face legal consequences from library owner.